I’ve been attempting to create a protocol and delegate between customized UI button and parent-child view controller. Briefly, I’ve a guardian view controller, a toddler view controller, and a customized UI button. Customized UI button and baby VC are beneath guardian VC. I created a protocol delegate for customized UI button and conformed it by guardian VC. I need to change baby VC’s view body origin with a faucet on customized UI button. I additionally need to change the picture of customized UI button once I tapped. Nonetheless, when I attempt to change the picture of customized UI button and likewise name delegate operate, baby VC view has some undesirable impact. Right here is the pattern code:
Father or mother View Controller
class ParentViewController: UIViewController {
let childVC: ChildViewController = {
let childVC = ChildViewController()
childVC.view.translatesAutoresizingMaskIntoConstraints = false
return childVC
}()
let customButton: CustomUIButton = {
let button = CustomUIButton(body: .zero)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
override func viewDidLoad() {
tremendous.viewDidLoad()
view.backgroundColor = .white
setupCustomButton()
setupChildVC()
}
override func viewDidLayoutSubviews() {
tremendous.viewDidLayoutSubviews()
applyConstraints()
}
personal func setupCustomButton() {
view.addSubview(customButton)
customButton.delegate = self
}
personal func setupChildVC() {
addChild(childVC)
view.addSubview(childVC.view)
childVC.didMove(toParent: self)
}
personal func applyConstraints() {
let childVCConstraints = [
childVC.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
childVC.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
childVC.view.heightAnchor.constraint(equalToConstant: 65),
childVC.view.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -200)
]
let customButtonConstraints = [
customButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
customButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -50),
customButton.heightAnchor.constraint(equalToConstant: 70),
customButton.widthAnchor.constraint(equalToConstant: 70)
]
NSLayoutConstraint.activate(childVCConstraints)
NSLayoutConstraint.activate(customButtonConstraints)
}
}
extension ParentViewController: CustomUIButtonDelegate {
func customUIButtonDidTap() {
self.childVC.updateView()
}
}
Baby View Controller
class ChildViewController: UIViewController {
var isHidden: Bool = false
override func viewDidLoad() {
tremendous.viewDidLoad()
view.backgroundColor = .systemBlue
}
func updateView() {
if isHidden {
UIView.animate(withDuration: 0.3) {
self.view.body.origin.y -= 40
self.isHidden = false
}
} else {
UIView.animate(withDuration: 0.3) {
self.view.body.origin.y += 40
self.isHidden = true
}
}
}
}
Customized UI Button
protocol CustomUIButtonDelegate: AnyObject {
func customUIButtonDidTap()
}
class CustomUIButton: UIButton {
weak var delegate: CustomUIButtonDelegate?
var isDoing: Bool = false
let image1: UIImage = {
let picture = UIImage(systemName: "chevron.proper") ?? UIImage()
return picture
}()
let image2: UIImage = {
let picture = UIImage(systemName: "chevron.left") ?? UIImage()
return picture
}()
override init(body: CGRect) {
tremendous.init(body: body)
setTitle("", for: .regular)
backgroundColor = .systemRed
layer.cornerRadius = 35
layer.shadowColor = UIColor.systemCyan.cgColor
layer.shadowOpacity = 0.8
layer.shadowOffset = CGSize(width: 0, top: 0)
addTarget(self, motion: #selector(didButtonTapped), for: .touchUpInside)
}
@objc func didButtonTapped() {
self.isDoing = !isDoing
self.setImage(isDoing ? image1 : image2 , for: .regular)
delegate?.customUIButtonDidTap()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been applied")
}
}
If I dont change the picture of customized UI button, it really works completely. I’m not positive why setting picture of button has this impact.
Customized UI Button goal:
@objc func didButtonTapped() {
// self.isDoing = !isDoing
// self.setImage(isDoing ? image1 : image2 , for: .regular)
delegate?.customUIButtonDidTap()
}