I have a static group of cells, a few groups actually, and for some reason the pull to refresh function is enabled, I can't figure out where, at least in Xcode Interface builder an option is to disable that. I assume I'll have to do it programmatically.
Does anyone know how this needs to be done in Swift?
If you're using UITableViewController, it should be something as simple as
self.refreshControl = nil
In storyboard, go to your Attributes Inspector for your View Controller and disable it there where it says 'Refreshing':
For swift 4 you can using
self.yourTableView.refreshControl = nil
Related
I've got a subclass of UIView, let's say it's class DemoView: UIView { } which contains UILabel and UIButton. I needed to group it and add UIAccessibilityCustomAction so I've overriden the var accessibilityElements: [Any]? and used union to connect both elements. I've also assigned "Users" string to accessibilityLabel.
From user perspective this works as it should, VoiceOver reads Users and then user can select custom action which is named Edit.
Problem is that I don't know how can I fire this custom action from UITests. I know that XCUIElement contains array of UICustomActions and I can get its selector but then what?
I talked to Apple Engineers during WWDC19 Accessibility and Testing Labs and they said it is not possible right now. The reason why accessibility is not available during testing are security concerns. What they also said is that they don't use UITests for testing UIAccessibility and when creating accessibility elements support two cases - when there are UITests running and not.
I recommend making a suggestion using Feedback Assistant.
The purpose you're tring to reach isn't possible currently with iOS13 and Xcode 11.
The UITesting framework doesn't access the application code as unit tests do: you can't get an instance to perform selector + the array of custom actions is nil when in UITest ⇒ every custom action isn't reachable and then can't be fired at all.
XCUITEST works thanks to the accessibility properties like accessibilityIdentifier but isn't definitely designed to simply work for VoiceOver (inconceivable and incomprehensible in my view).
I hope that something new with UI testing will be introduced during the next WWDC for REAL accessibility testing.
For anyone else stuck on this, if you have a direct reference to the UIView in question, I've (well, a coworker of mine) found the following 'hack' to work quite well.
let view: UIView = YourViewWithCustomAction()
let customActionName: String = "<Your custom action name here>"
let action: UIAccessibilityCustomAction = view.accessibilityCustomActions!.first(where: { $0.name == customActionName })!
_ = action.target!.perform(action.selector, with: action)
As a disclaimer, this might only work when you have a custom UIView subclass that implements its own override var accessibilityElements.
It's a well known feature in XCode that we can hold control an object from interface builder to swift file to make a connection..
Is there any shortcut to make the connecttion by default an action instead of outlet ...? this is useful when dragging UIButtons.
Regarding custom shortcuts, As far as i heard. Probably No.
Many developers have had this problem. fortunately Xcode 10 is here to help! Now, if you command-drag above the first function, it'll default as an outlet. Below the first function, the default is an action. Brilliant!
I am trying to navigate to a UIViewController using Swift 2.3. To be more precise, I am trying to reload the UIViewController that is currently active. I do not know which view the user currently has active, so this must be defined dynamically.
I have tried several approaches, but they all result in either compile or runtime errors.
Is something like this possible?
let activeViewIdentifier = ??? // Get currently active view identifier as a string
self.performSegueWithIdentifier(activeViewIdentifier, sender:self)
You can get like this :
Objective-C :
self.navigationController.topViewController.restorationIdentifier
Swift :
self.navigationController?.topViewController?.restorationIdentifier
I think you have some issues with your architecture; it's not the best approach to reload just everything on some View Controller you can chose;
Much better way of thinking is to determine, what exactly you want to reload and add methods to reload only thus things
Anyway, if my answer hasn't assure you, consider replacing existing view controller with new and presenting it with some animation, or without it; so your general algorithm may look like this:
Get new VC from storyboard, or creating new instance, if you don't prefer to use it
Push it over your existing controller
Reload stack of navigation controller, in which you are now
you can try this
let activeViewIdentifier = self.navigationController?.childViewControllers[(self.navigationController?.childViewControllers.count)!-1]
You can use the restorationIdentifier, it's right above the Storyboard identifier and it's a UIViewController property.
let activityIdentifierStr = activeViewIdentifier?.restorationIdentifier
self.performSegueWithIdentifier(activityIdentifierStr!, sender:self)
How do I test whether a view is hidden using XCUITest? A view is sometimes hidden (set in Xcode like this: Hidden view)
How do I test for that in XCUITest using Swift? In my case, the view is just a label. I tried something like this: XCTAssertFalse(app.staticTexts["pushNotificationInstruction"].accessibilityElementsHidden) . But that's not it. accessibilityElementsHidden is not the same as the view is hidden. Thanks.
Unfortunately, this is not currently possible using XCUITest. Here is a developer forum thread where an Apple engineer suggested filing a radar for this exact issue:
https://forums.developer.apple.com/message/46271
I have personally filed a couple radars relating to the limitations imposed by not being able to access certain properties of UIViews from within an XCUITest. I encourage you to do the same and provide details of the scenarios you are blocked from testing because of this deficiency in XCUITest.
You can assert that the view does not exists and use another test to check the scenario when it does exists. Maybe a bit fragile, but that would cover you case.
let viewControllerShown = app.otherElements["view_myviewcontroller"].waitForExistence(timeout: 5)
XCTAssert(viewControllerShown)
let instructionViewExists = app.staticTexts["pushNotificationInstruction"].exists
XCTAssertFalse(instructionViewExists)
An expedient solution is to carry the visibility state of the view in its accessibilityidentifier.
In your view controller:
view.isHidden = hideView
view.accessibilityidentifier = "view1"+(hideView ? "hidden" : "")
In your tests:
XCTAssert(app.otherElements["view1"].exists)
or
XCTAssertFalse(app.otherElements["view1"].exists)
Looking at the documentation of exist:
The fact that an element exists does not imply that it is hittable.
Elements can exist offscreen, or exist onscreen but be hidden by
another element, causing their isHittable property to return false.
It means that you can check:
if uiElement.exists && uiElement.isHittable {
XCTFail()
}
I have created a custom view (Quantity View) with nib file in Swift. I have created some IBOutlets & IBActions (for buttons, labels etc.) in my custom view.
I tried to use this custom view (Quantity View) by assigning class name to a UIView in my storyboard.
It's showing me all the IBOutlets & IBActions in the Connections Inspector, as shown in this screenshot: .
I just want to show only delegate for the Custom view.
Possible Answer:
I thought I can use the -viewWithTag to get the views instead of Outlets.
But, I want to know if it's possible with having Outlets also or if there is much better way to do this?
What are the other possible ways (optimum) to handle this situation?
You can also consider the following solution:
You can take the subviews of your QuantityViews(custom view) and you can identify the specific views by its frame origin.
Note : you should know the customview subviews frame
Its not possible to hide IBOutlets from storyboard if you declare the class members as IBs (IBOutlets or IBActions).
The IBOutlets or the IBActions are just indicators to the interface builder so that it can show the names on it when you try to bind them it actually calls the setValue: forKey: method to set the view's reference to the IBOutlet property.
Now if you try to access an subview from the file's owner class without any IBoutlets you need to have a pointer to point it, so for that either you can get the reference using ObjectID which is assigned to the subview by the interface builder or you can get it using the viewWithTag: method.
The ObjectID you need to find all time when you add or replace a subview from the view, so better and convenient approach is to use tag property of UIView class.
So my conclusion to this problem is to access the views using the viewWithTag method you mentioned earlier.
I think your way is correct. But sometimes Xcode doesn't work correctly.
The following makes the IBOutlets and IBActions reappear and work properly:
Clean project your project in Xcode.
Quit Xcode completely.
Delete all contents of ~/Library/Developer/Xcode/DerivedData/.
Restart MacOS just in case.
I hope you will resolve that :)