I am writing UITest cases for my iOS Swift app. In the app I have created a custom right item button on the navigation bar in this way:
let barButtonItem = UIBarButtonItem(customView: customView)
navigationItem.rightBarButtonItem = barButtonItem
Now I don't know how to access this custom right item button in XCUITest and really need some help. Thanks in advance.
You cannot access a UIBarButtonItem, because it is not a real UIElement (it is not a UIView subclass), but you probably want to access the UIButton inside your right bar button item anyway.
There are several ways how you could access the button, here are two ideas:
1. Query the first button in the navigation bar
let rightNavBarButton = XCUIApplication().navigationBars.children(matching: .button).firstMatch
XCTAssert(rightNavBarButton.exists)
That way you access the first UIButton inside a UINavigationBar.
This only works if there is only one button in your navigation bar. So it will break when you add another button.
2. Use an accessibility identifier
You can define a accessibility identifier for the button inside your right bar button item and use that to access it during the test:
In your app:
let barButtonItem = UIBarButtonItem(customView: customView)
barButtonItem.accessibilityIdentifier = "navbarRightItem"
navigationItem.rightBarButtonItem = barButtonItem
In your test:
let rightNavBarButton = XCUIApplication().navigationBars.buttons["navbarRightItem"]
XCTAssert(rightNavBarButton.exists)
Just make sure you are using accessibilityIdentifier and not accessibilityLabel. Because accessibilityLabel will be read by VoiceOver for handicapped users and should contain useful text.
You have to assign an accessibilityIdentifier to the button
barButtonItem.accessibilityIdentifier = “barButtonItemID”
If didn’t work set IsAccessibilityElement to YES/true
Related
I would like to place a bluetooth icon in my Navigation Bar, to display a connected / disconnected status.
I tried to add a BarButtonItem, set the image as my bluetooth icon, and disabled and enabled this Button. This works fine so far, and is looking ok to me, but I don't want to have this button clickable, so that it doesn't change the color on clicking on the icon.
Is this possible, or is there a way to put a UIImageView into the Navigation Bar?
Thanks!
Try disabling touch events using:
myBarButtonItem.isUserInteractionEnabled = false
navigationItem.rightBarButtonItem?.isEnabled = false
Add following code will fix your issue.
let btnBluetooth = UIButton()
btnBluetooth.setImage(#imageLiteral(resourceName: "icon_bluetooth"), for: .normal)
btnBluetooth.setImage(#imageLiteral(resourceName: "icon_bluetooth"), for: .highlighted)
btnBluetooth.tintColor = .red
let barButton = UIBarButtonItem(customView: btnBluetooth)
self.navigationItem.rightBarButtonItem = barButton
This code will add custom button where you can manage image for normal and highlight mode. For bluetooth state management, change tintColor of UIButton which you have added in UIBarButtonItem as custom view.
If you click on button, this will not change color of image.
If you don't want to add UIButton you can add UIImageView by following code.
let imgBluetooth = UIImageView(image: #imageLiteral(resourceName: "icon_bluetooth"))
imgBluetooth.tintColor = .red
let barButton = UIBarButtonItem(customView: imgBluetooth)
self.navigationItem.rightBarButtonItem = barButton
Also, make sure you have selected Render As as Template Image for your bluetooth icon which is added inside Assets.xcassets to affect tintColor. Otherwise image will be display as original. See follow:
I want to set the right button item to be this:
It has the title and the down image.
But in storyboard, I can not do that:
I only can set one of the title and image, if I set image, I can not set the title, if I set the title, I can not set the image.
I have tried use the UIButton and the Button Bar Item to do it, get the same result.
Some friend know how to do with that?
You can simply add drag UIButton to rightBarItem in storyBoard . and customise that button as per your needs ..
Check View hierarchy after adding UIButton .
you can try this add the custom view to your bar button item
var RightView = UIView(frame: CGRectMake(0, 0, 100, 44))
// you can add in RightView, your title in uilable and your image in imageview
var RightBarButton = UIBarButtonItem(customView: RightView)
self.navigationItem.rightBarButtonItem = RightBarButton
How can I hide my left bar button item?
In my storyboard I dragged a Navigation Bar onto my View Controller, then a Bar Button Item. Under certain conditions I want to hide the Bar Button Item.
None of this works:
override func viewDidLoad() {
self.navigationItem.leftBarButtonItem = nil
self.navigationItem.leftBarButtonItems = []
self.navigationItem.setLeftBarButtonItems([], animated: true)
}
I dragged a Navigation Bar onto my View Controller
Well, don't! There is a big difference between a navigation controller interface, where you set the navigationItem, and a loosey-goosey navigation bar just sitting there in the interface, which is what you have.
Embed your view controller in a UINavigationController and do things the right way. Then setting your navigationItem and its properties will work as expected.
You can't access to self.navigationItem.leftBarButtonItem because you manually drag navigationBar from storyboard. I would suggest to do the following instead:
add an IBOutlet of BarButtonItem (eg: barButton) that you created in storyboard
barButton.title = ""
barButton.isEnable = false
This will hide your BarButtonItem, and you can simply show it back later.
I had setup two UIBarButtonItem on the left. Below is the screen shot of the wireframes of the screen, captured from debugging view hierarchy. Red box is the default back button and green box is the menu button.
From the screenshot, there is a gap between the back button image and menu button. The back button's view is occupying the extra space. I'm trying to figure out a way to get these two button close to each other.
I removed the "Back" text for the back button:
let backItem = UIBarButtonItem()
backItem.title = ""
self.backBarButtonItem = backItem
And added menu button:
let btn = UIBarButtonItem()
btn.customView = menu // it's a UIButton
self.leftItemsSupplementBackButton = true
self.leftBarButtonItem = menu
If it truly is the back buttons view, then just reduce the size of its views frame and you are good to go.
If it is an attribute of the main back bar button item they give you, then make a custom one that looks the same and give it the appropriate size.
If you are using a flexible space bar button item, then use a fixed space bar button item and set it appropriately.
You can also modify the value of a bar button view's location through the insetInPlace() that you use on the frame, but that will take some experimenting on the correct values to be used.
There are few options:
One is to insert an invisible bar button item and give it negative width like shown here https://stackoverflow.com/a/31804099/520810
Alternatively you can adjust image insets https://stackoverflow.com/a/22742322/520810
I'm trying to add a UISegmentedControl to a UIToolbar using IB within xCode.
Whilst this is easy using a xib file, (create a view, add a toolbar to the bottom of the screen and drag on a UISegmentedControl onto the toolbar), it seems 'impossible' using storyboards.
I have a UIViewController scene embedded in a UINavigationController...
I have the following settings on the NavigationController...
I seem to be able to add UIBarButtonItems to the toolbar in the ViewController, not a UISegmentedControl as I can with xibs.
It even seems impossible to do via code...
let segmentControl = UISegmentedControl(items: ["One","Two"]);
let segmentedControlButtonItem = UIBarButtonItem(customView: segmentControl);
let barArray = [segmentedControlButtonItem];
self.navigationController?.setToolbarItems(barArray, animated: false);
Surely this is doable via storyboards? I can add UISegmentControls to the top bar in the Navigation Controller, (via a UIView) but not to the bottom toolbar.
How can this be done?
You need to set the toolbarItems of your own ViewController, this will propagate to the NavigationController:
self.toolbarItems = barArray
I haven't found a way of adding a SegmentedControl via Storyboards, which I would prefer as well.