I am using pushViewController like the following code:
let vc = A()
self.navigationController?.pushViewController(vc, animated:true)
I want to add a navigationItem to the page that opens. This code working on new versions but not working on iPhone 5(iOS 9.3) Simulator and iPad(10.3.3)
class A: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
configureNavigationItem()
}
func configureNavigationItem() {
let buttonLogo = UIButton(type: .custom)
buttonLogo.setImage(UIImage(named: "logo"), for: .normal)
buttonLogo.setTitle("", for: .normal)
buttonLogo.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: -9, right: 0)
let itemLogo = UIBarButtonItem(customView: buttonLogo)
self.navigationItem.setLeftBarButton(itemLogo, animated: true)
}
}
Nothing appears in old versions. How can I solve this?
The problem is that your UIButton has zero size. You need to give it a size!
buttonLogo.sizeToFit()
let itemLogo = UIBarButtonItem(customView: buttonLogo)
The reason your code works in iOS 11 is that it uses autolayout to size the button as a customView. But that is a new feature of iOS 11.
Add image with Rendering Mode something like below.
let menuButtonImage = UIImage(named: "logo")?.withRenderingMode(UIImageRenderingMode.alwaysOriginal)
buttonLogo.setImage(menuButtonImage, for: .normal)
And then check
Related
I add a custom button to the tabBar in my MyViewController.viewDidLoad(subclass of UITabBarController)
But I find it doesn't response the selector.
If I delay one second to add button(in DispatchQueue.main.asyncAfter closure) ,it works OK.
I think it's not the right way to resolve it.
func addButton() {
let button = UIButton(type: UIButton.ButtonType.custom)
button.bounds = CGRect(x:0,y:0,width:30,height:30);
button.backgroundColor = UIColor.red
button.center = CGPoint(x:self.tabBar.frame.size.width/2, y:self.tabBar.frame.size.height/2 - 20);
button.addTarget(self, action: #selector(click(button:)), for: UIControl.Event.touchUpInside)
tabBar.addSubview(button)
}
You have added button to UITabBar of UITabBarController as half of part of the button would appear above the Tabbar and half of below the Tabbar as per frame.
So I guess you will not get click on part of that button which is out of Tabbar(above Tabbar) would not get touch. I you will make button little big OR try to click with arrow in simulator, you will get idea.
If you need to have button at bottom but slightly upper, then please create custom Tabbar to achieve design like this. Or else you can add that button into UITabBarController’s view instead of Tabbar.
class MyTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.addButton()
}
func addButton() {
let button = UIButton(type: UIButton.ButtonType.custom)
button.bounds = CGRect(x:0,y:0,width:50,height:50); //1
button.backgroundColor = UIColor.purple
button.center = CGPoint(x:self.tabBar.frame.size.width/2, y:self.tabBar.frame.size.height/2 - 50 + self.tabBar.frame.origin.y); //2
button.addTarget(self, action: #selector(click(button:)), for: UIControl.Event.touchUpInside)
button.layer.cornerRadius = button.frame.size.height/2
button.layer.masksToBounds = false
button.layer.shadowColor = UIColor.black.withAlphaComponent(0.5).cgColor
button.layer.shadowRadius = 5.0
button.layer.shadowOffset = CGSize(width: 0.0, height: 5.0)
button.layer.shadowOpacity = 0.5
//tabBar.addSubview(button) //3
self.view.addSubview(button). //4
}
#objc func click(button: UIButton) {
print("Button get clicked")
}
}
I have marked four things with commented by numbers at the end of lines, that you can make to your code and try.
I have read the manual (https://material.io/develop/ios/components/buttons/), but still have not understood how to do it.
class FloatingButtonController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let floatingButton = MDCFloatingButton()
floatingButton.setImage( UIImage(named: "plus"), for: .normal)
floatingButton.backgroundColor = .white
floatingButton.setElevation(ShadowElevation(rawValue: 6), for: .normal)
floatingButton.addTarget(self, action: #selector(btnFloatingButtonTapped(floatingButton:)), for: .touchUpInside)
self.view.addSubview(floatingButton)
}
#objc func btnFloatingButtonTapped(floatingButton: MDCFloatingButton){
floatingButton.collapse(true) {
floatingButton.expand(true, completion: nil)
}
}
}
My project on the screen. As you can see - the button is missing on the screen. When you click on a blank screen errors appear.
Button touch target does not meet minimum size guidlines of (48, 48). Button: >, Touch Target: {0, 0}
Screenshot of my project
Tell me, please, what am I doing wrong? And how do I get the job right?
You didn't set the frame to button. You need to specify (x, y) position to place button in view.
floatingButton.frame = CGRect(x: 300, y: 300, width: 48, height: 48)
To add button target the button should have size atlease 48x48.
You could constraint it manually or set frame.
OR you could add button via Storyboard too.
I have been trying to fix an issue that I encountered with a tableviewcontroller.
The sections within the tableviewcontroller are views:
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let sectionLabel = UILabel()
sectionLabel.text = Catalog.sharedInstance.allSections[section - 1].name.localized(lang: defaults.string(forKey: "language")!)
sectionLabel.font = UIFont(name: "Centabel Book", size: 25)
sectionLabel.backgroundColor = UIColor.white
sectionLabel.clipsToBounds = true
return sectionLabel
}
If I try to add a button programatically to put it over the tableview
let actionButton = JJFloatingActionButton()
override func viewDidLoad() {
super.viewDidLoad()
// Configuration of the Floating Action Button
actionButton.buttonColor = .red
actionButton.addItem { item in
self.performSegue(withIdentifier: "goToSettings", sender: nil)
}
actionButton.display(inViewController: self)
actionButton.clipsToBounds = true
// This doesn't work. It is to bring the button to the front. Now it is hidden by the sections.
view.bringSubviewToFront(actionButton)
// Checks if the language setting is nil, which means it is the first time you run the application. If then... selects English as default.
if defaults.string(forKey: "language") == nil {
defaults.set("en", forKey: "language")
}
}
... I don't know why but the viewForHeaderInSection hides the button. You can check it in the picture below:
floating button hided by the headersection
I tried to use the method:
view.bringSubviewToFront(actionButton)
and also:
actionbutton.superview?.bringSubviewToFront(actionButton)
But none of this brings the button to the front.
I am using a floating action button from github called JJFloatingActionButton. But I tried to add a simple UIButton and I got the same error. This is the code that also gave me the same error inside viewDidLoad:
let button = UIButton(frame: CGRect(x: 100, y: 1000, width: 100, height: 50))
button.backgroundColor = .green
button.setTitle("Test Button", for: .normal)
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
self.view.addSubview(button)
Again the same error. You can check the picture:
adding a simple UIButton happens the same problem
May be you can help me with that.
Thanks in advance.
You could try to use a regular UIViewController (not UITableViewController) and add the UITableView by hand.
Like that you would have better control over the view hierarchy.
Please take a look at my screenshot, the blue "Back" text always show on iphone plus (6s plus, 7 plus for both simulator and real device) . It does not show on smaller screen iphone. I tried lot of way to hide/change it from present/previous controller but no luck.
So why does it work on smaller iphone but not the plus one ?
Can anyone help me:(. Thanks.
Here is the code:
#IBAction func filter(_ sender: Any) {
let view:FilterViewController = self.storyboard?.instantiateViewController(withIdentifier: "FilterViewController") as! FilterViewController
view.superVC = self
view.currentFilter = currentFilter
self.setLeftCloseNavigation()
self.navigationController?.pushViewController(view, animated: true)
}
func setLeftCloseNavigation(){
self.navigationController?.navigationBar.backgroundColor = UIColor.clear
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.layer.mask = nil
self.navigationController?.navigationBar.backIndicatorImage = UIImage(named: "icon_close")?.withRenderingMode(.alwaysOriginal)
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "icon_close")?.withRenderingMode(.alwaysOriginal)
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
And here is the viewDidLoad in pushed controller:
override func viewDidLoad() {
super.viewDidLoad()
statusBar = UIColor.black
setResetNavigation() }
func setResetNavigation(){
navigationItem.hidesBackButton = false
let skipButton = UIButton(frame: CGRect(x: 0, y: 0, width: 70, height: 30))
skipButton.setTitle("Reset all".localized(), for: .normal)
skipButton.setTitleColor(UIColor.black, for: .normal)
skipButton.titleLabel?.font = UIFont(name: "HJGothamMedium", size: 16)
skipButton.addTarget(self, action: #selector(resetAllClicked), for: .touchUpInside)
let skip = UIBarButtonItem(customView: skipButton)
navigationItem.rightBarButtonItem = skip
}
This is the view hierarchy
Add this function :
override func viewDidAppear(_ animated: Bool) {
setResetNavigation()
self.navigationController?.navigationBar.backItem?.title = ""
}
try this
self.navigationItem.hidesBackButton = true
Or Check your storyboard it will remain
Use the below line to remove the text
navigationController?.navigationBar.topItem?.title = ""
You can inspect your UI hierarchy and if found related view then remove that view :
You can also invoke the view debugger by choosing View UI Hierarchy from the process view options menu in the debug navigator, or by choosing Debug > View Debugging > Capture View Hierarchy.
To hide the back text you need to set navigation item title to space character on the view controller that pushes the presented view controller:
self.navigationItem.title = " "
Be aware you have to set it on the previous view controller and not on top most one. Also you have to set a space character and not an empty string !!!
Also you can do this directly on storyboard
From below code you can set backButton text colour to any colour you want.You can simply set backButton to clear textColor. So, It won't be visible when it presents.
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UINavigationBar.classForCoder() as! UIAppearanceContainer.Type]).setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.clear], for: .normal)
Update: If you want to go for a different approach.Check this post How to customize the navigation back symbol and navigation back text? and accepted answer.
Using pod 'Player' in an iOS 9.0 app to play a video. I've subclassed Player class to add a UIButton overlay for closing the window.
It appears fine and has highlighting animation when tapped, but closeTapped isn't called when touching up inside.
import UIKit
import Player
class PlayerViewController: Player, PlayerDelegate {
func install() {
view.frame = presentor.view.bounds
presentor.addChildViewController(self)
presentor.view.addSubview(view)
didMove(toParentViewController: presentor)
let closeImage = UIImage(named: "close")!
let closeButton = UIButton(type: .custom)
view.addSubview(closeButton)
closeButton.setImage(closeImage, for: .normal)
closeButton.autoPinEdge(toSuperviewEdge: .top, withInset: 25)
closeButton.autoPinEdge(toSuperviewEdge: .right, withInset: 15)
closeButton.autoSetDimensions(to: CGSize(width: 50, height: 50))
closeButton.addGestureRecognizer(UITapGestureRecognizer())
closeButton.addTarget(self, action: #selector(closeTapped), for: .touchUpInside)
}
func closeTapped() {
logger.debug("Player close tapped")
}
}
I also tried having closeTapped(sender: Any?), didn't help.
Why isn't closeTapped called?
You don't need to add a TapGestureRecognizer to the button. For swift 3.0 you can do it like this:
button.addTarget(self, action: #selector(closeTapped(sender:)), for: .touchUpInside)
func closeTapped(sender: UIButton) {
}
I think the top of your button u added a UITapGestureRecognizer(). Which itself has a #selector. So Your button default .touchUpInside controller is not calling.
Try with commenting
//closeButton.addGestureRecognizer(UITapGestureRecognizer())
this line.
Let me know is this helpful or not.