UIButton doesn't work in child view controller - swift

UIButton gestures doesn't recognize in child view controller.
UIButton add targer work (button get target action)
User interaction is turned on everywhere, button size is okay. I try to set childVC as main, and then all work good, debug view hierarchy said that button view over other elements. IDK where is problem. I can provide more code, just tell me.
Add target code:
view.buttonOfLanguageFromTranslate.addTarget(self, action: #selector(self.openDetailView(_:)), for: .touchDown)
Add child VC code:
let childVC = ChildVC()
view.addSubview(childVC.view)
self.addChild(childVC)
childVC.didMove(toParent: self)
childVC.view.translatesAutoresizingMaskIntoConstraints = false
self.view.isUserInteractionEnabled = true
self.childVC = childVC
Button initialization:
var button: UIButton = {
let button = UIButton()
button.setTitle("Title", for: .normal)
button.setTitleColor(.black, for: .normal)
button.setTitleColor(.green, for: .selected)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()

The problem was with
childVC.translatesAutoresizingMaskIntoConstraints = false
(in mainVC)
When i remove it, childVC recognise my tap
and i dont set additional size for childVC, view of childVC is display correct but not childVC. (as i think)

Related

UIHostingController resets custom leftBarButtonItem when pushed

I have a view controller in a navigation controller. In viewDidLoad:
let button = UIButton()
button.setImage(Theme.Icon28.back.withRenderingMode(.alwaysTemplate), for: .normal)
button.addTarget(self, action: #selector(didTapBackButton), for: .touchUpInside)
button.imageEdgeInsets = Constants.buttonImageEdgeInsets
button.accessibilityIdentifier = "nav_btn_back"
navigationItem.leftBarButtonItem = button
This sets up my custom back button. Now I want to push a UIHostingController:
navigationController?.pushViewController(UIHostingController(rootView: SomeView()), animated: true)
With SomeView as:
struct SomeView: View {
var body: some View {
Text("Hello World")
}
}
Now when I push the UIHostingController the back button will change back to the default system back button, the leftBarButtonItem has lost my custom button. Has anyone else run into this issue?
Why is it overriding my custom button?

Swift NavBar Hide NavBarItem

Inside of my view controller I have a navBar with an item on the left side and right side. I also have 2 buttons inside of the view controller. I have it so each button does different functionality. I also have the swift file connected to the view.
My issue is that when I do either of the code below inside of my button actions the NavBar Items do not change. I don't know how to remove and add the item back, I also dont understand what Im doing wrong.
self.navigationItem.rightBarButtonItem?.isEnabled = false
self.navigationItem.rightBarButtonItem?.tintColor = UIColor.clear
self.navigationItem.rightBarButtonItem?.isEnabled = true
self.navigationItem.rightBarButtonItem?.tintColor = UIColor.red
Connect Navigation Bar from storyboard to View Controller Class
#IBOutlet var navBar: UINavigationBar!
This will hide Button
navBar.topItem?.rightBarButtonItem?.isEnabled = false
navBar.topItem?.rightBarButtonItem?.tintColor = UIColor.clear
This will show Button
navBar.topItem?.rightBarButtonItem?.isEnabled = true
navBar.topItem?.rightBarButtonItem?.tintColor = UIColor.red
Sorry, i can't make comment due to low reputetion. Which IDE are you using?
The answer of #dharmesh works, if you create the button programmatically:
let btn = UIButton(type: .system)
btn.setTitle("Indietro", for: btn.state)
btn.addTarget(self, action: #selector(annulla), for: .touchUpInside)
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: btn)
If you use the one from the IDE it depends on the IDE itself to store the values to hide or change it

Nav button needs to go form the last view to the first view

Hello, I have provided the link above to show a visual view of what I am trying to accomplish. So each button is a segue to the next view except the last button is not which is intended. The last two views with the back buttons at the top that are automatically included because of the nav controller I want to have those back buttons go to the first view controller. How can I do this either with xcode and swift?
If you want to remove all the navigation controller then use this code
Put this code in the button selector method
self.navigationController!.viewControllers.removeAll()
OR
navigationController?.popToRootViewController(animated: true)
OR
If you don’t have a Navigation Controller and use dismissViewController method, you still can use:
view.window?.rootViewController?.dismiss(animated: true, completion: nil)
Now comes the back button code:
override func viewDidLoad() {
super.viewDidLoad()
var backbutton = UIButton(type: .Custom)
backbutton.setImage(UIImage(named: "BackButton.png"), forState: .Normal) // Any image can be used. download back button image from any site or whatever you wanna use.
backbutton.setTitle("Back", forState: .Normal)
backbutton.setTitleColor(backbutton.tintColor, forState: .Normal) // You can change the TitleColor
backbutton.addTarget(self, action: "backAction", forControlEvents: .TouchUpInside)
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backbutton)
}
func backAction() -> Void {
//here put code from above whichever you wanna use for example I'm using one
self.navigationController?.popToRootViewController(animated: true)
}

Swift Safe Area Layout not activating properly

I am learning some auto layout programatically and I want to add a button on the bottom part of the screen, just above the safe area.
I know the code is working, because I tested it in another project, I think it is a conflict because I get to this viewController from another one.
The code for my button
private let previousButton : UIButton = {
let button = UIButton(type: .system)
button.setTitle("Prev", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
The code for setting up my constraints
fileprivate func setupBottomControls() {
view.addSubview(previousButton)
previousButton.backgroundColor = .red
view.addSubview(previousButton)
NSLayoutConstraint.activate([
previousButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
previousButton.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
previousButton.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
previousButton.heightAnchor.constraint(equalToConstant: 50)
])
}
Like I said this code is working in another project but I think it is in conflict because of how I called this viewController.
This is a code from the first view controller that make the new viewController(GettingStartedController) to be shown, here it will be the button mentioned above.
func switchVC(){
//enter GettingStarted controller
let controller = GettingStartedController()
view.addSubview(controller.view)
present(UINavigationController(rootViewController: controller), animated: true,completion: nil) //used when no animation is present
}
I think the problem is here any ideas on how to change the call to the GettingStartedController so that will see the Safe Area the right way?
Check my code solution. I added your function to the button when it is tapped and it now presents the GettingStartedController():
private let previousButton : UIButton = {
let button = UIButton(type: .system)
button.setTitle("Prev", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
button.addTarget(self, action: #selector(switchVC), for: .touchUpInside)
return button
}()
fileprivate func setupBottomControls() {
view.addSubview(previousButton)
previousButton.backgroundColor = .red
view.addSubview(previousButton)
NSLayoutConstraint.activate([
previousButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
previousButton.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
previousButton.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
previousButton.heightAnchor.constraint(equalToConstant: 50)
])
}
#objc func switchVC(){
//enter GettingStarted controller
let controller = GettingStartedController()
present(UINavigationController(rootViewController: controller), animated: true,completion: nil) //used when no animation is present
}

Custom UIButton as Navigation Item Back Button working, but does not show

let btnName = UIButton()
btnName.setImage(UIImage(named: "backIcon"), for: .normal)
btnName.addTarget(self, action: #selector(AddContactViewController.backAction), for: .touchUpInside)
let leftBarButton = UIBarButtonItem()
leftBarButton.customView = btnName
self.navigationItem.leftBarButtonItem = leftBarButton
It works fine, it does what is intended to do. However, on the navigation item it's invisible. But when I click on the area where it should be. It works.
Actually you may have two navigation bars one is of your current class and another is of your previous class.So, you can try by adding below code in your previous class.
override func viewWillDisappear(_ animated: Bool) {
self.navigationController!.navigationBar.isHidden = true
}
I also faced the same problem and it worked for me. May be it will help you.
Everything is ok, except you forgot to set the frame for your button, that's why it's not being shown.
let btnName = UIButton(frame: CGRect(x: 0, y: 0, width: 18, height: 17))
btnName.setImage(UIImage(named: "backIcon"), for: .normal)
btnName.addTarget(self, action: #selector(AddContactViewController.backAction), for: .touchUpInside)
let leftBarButton = UIBarButtonItem()
leftBarButton.customView = btnName
self.navigationItem.leftBarButtonItem = leftBarButton
Rather than hard-coding some frame values, you are better off calling the sizeToFit() method after setting the image, title, etc. I hit this problem today where a custom back button was showing OK on iOS11, but was not visible on iOS9.
btnName.sizeToFit()