I've added an MKMapView as a subview on one of my ViewControllers in an XIB. The map works alright in terms of showing directions. But the Legal text on the map (bottom left) shows as <unlocalized> instead of having a text saying Legal in whatever language is selected (or even English).
How do I fix this? Thanks.
Note: My app supports 6 languages if it makes a difference (but none of the XIBs are localized)
I couldn`t reproduce this but it seems like an issue in the localization file. This guy has a similar problem and resolved it by removing localization files (and creating new I think).
Of course, you can always set directly your localized string to Legal MKAttributionLabel, by getting it from MKMapView subviews, and using setValue(_:forKey:) with _innerText and _strokeText keys. But notice that this is private API :)
I can think of 2 possible solution but didn't. One is to check which subview of all your MKMapView's subviews for that specific label and add move it out of the window or scale it down to 0. The other one would be similar but by subclassing you MKMapView and try to hide this label in layoutSubviews method.
Related
I am having trouble locating XCUIElements on a screen for the app I am testing. I realize you can access a button for example via something like:
app.buttons[].elementBoundByIndex(0)
But the problem is sometimes, the component is not found. Like in a case where I have a Button in a cell in a UITableView. I try to make an XCUIElementQuery to find the button, and it is not there. I try to look for tables or tableviews or collection views and even though they are in the view controller, they are not found in UI Testing. The count of the returned array will be zero.
I attempted originally to record the test, but clicking the element I am trying to access did not work. Xcode detected it as an "Other Element" and when trying to tap during, playback the application does not advance.
Is there a high level way to access a component like a UIView high in the UI hierarchy to cascade down?
I didn't know this at the time, but what I was looking for was basically debugDescription:
Set a breakpoint when you hit the area you're trying to debug. Then
po print(app.debugDescription)
in the debug console. You will see the hierarchy then.
Ideally you should set an accessibilityIdentifier on your button and search for it via that. The accessibilityIdentifier should be unique for elements on the screen. You can set an accessibilityIdentifier in the Identity Inspector in Interface Builder (command-option-3) or in code directly. Once you have one, the query looks like:
app.buttons["SomeAccessibilityIdentifier"]
Ryan Poolos answer was the best answer for me as it solved my issue with nested UI Elements
We had to solve it by removing a few accessibility identifiers on superviews in the stack. Not ideal but did get it working without changing actual functionality. – Ryan Poolos
So with that in mind, I found the xib file with the element in question, selected the element, selected the tab "Show the Identity Inspector" on the right panel and unchecked the Accessibility checkbox.
I then did a recording of the element which resulted in:
[[[[[XCUIApplication alloc] init].scrollViews.tables childrenMatchingType:XCUIElementTypeOther] elementBoundByIndex:index] childrenMatchingType:XCUIElementTypeButton].element;
Notice how XCUIElementTypeOther is in the query. This was not the case when the accessibility identifiers were enabled as I would get:
[[[[[XCUIApplication alloc] init].scrollViews.tables.otherElements containingType:XCUIElementTypeStaticText identifier:#"username"] childrenMatchingType:XCUIElementTypeButton].element tap];
Obviously I wouldnt know the username as it would always change and this was a major problem. But after removing the accessibility identifiers,
containingType:XCUIElementTypeStaticText identifier:#"username"
changed to
childrenMatchingType:XCUIElementTypeOther] elementBoundByIndex:index
SUCCESS :)
In my own experience you being able to find an element (an UIView in your case as UIButton inherits from UIview) through its accessibilityIdentifier depends on how you added it to the view.
I assume that in your case you added the button to the cell programatically with addSubView. If that's the case, probably you will not be able to access to it. I've had the same problem and asked the question here but no proper solution at the moment, so my advice is try to avoid adding views with addSubView the moment...
I know this has been asked before, but none of these solutions work, and that's the reason of my posting. Please do not close before considering my case.
My plist already has UIViewControllerBasedStatusBarAppearance = false.
I have already tried applying deltas, but to no result.
Changing the top level view frame in ViewWillAppear (like self.view.frame) did not succeed.
I thought of increasing the view height (storyboard attribute inspector), in combination with deltas, but my top level view X, Y are disabled in storyboard attribute inspector.
My main view doesn't have any children views because I load them into main view either dynamically or load them from XIBs which are again shared by more than view controllers. These XIBs provide layout for both Portrait and Landscape. I don't know what approach is ideal for this kind of configuration, but I would like it better if solution lies along these lines.
This approach worked partially, but gave me inconsistent results.
What makes the solution tricky is the fact that I have to support all 4 orientations - this is something I handle in code via didRotate and willRotate delegates for my other views, but failing to do it for statusbar.
Please help...
Could this link be of any help?
You might have to use the new setEdgesForExtendedLayout: method to get this working consistently?
Also, have a look at these official docs if you haven't already done so.
I ended up writing my own function to shift my all subviews (remember, not top level views whose frame is fixated by IB).
It didn't spoil my work but imagine if this was the case for a very big project with so many screens, the limitations would have made it a nightmare.
Consider the following two toolbars that are in the same project of mine:
Notice that these toolbars look different? The problem is that they were both created by dragging and dropping them into IB, and I didn't change any of there associated properties. All that I did change was adding the flex controller, and change the text on the initial UIButtonBarItem. Other than that, these Toolbars have not been modified and, furthermore, I've verified that their properties are exactly the same in the Attribute inspector.
How or why are they different? Furthermore, how can I get the first, bluish UIToolbar to look like the grey one since the available Black Opaque and Black Translucent styles look nothing like the grey one?
Am I missing something? This doesn't make any since.
I've found why this is happening but I'm a bit clueless on how to change this. See this, new question regarding a fix for this issue.
These Toolbars are changed due to internal Xib settings that are specified when the Xib is created. In the first example, when I created the UIViewController I must have unchecked the Target for iPad check box, even this is for an iPad project.
This changed the default size of the initial UIView that was in the Nib. I always cut off the statusbar and set the view to be freeform in sizing as soon as I create a UIView within a Xib file, so I can never tell by looking at my views whether they were targeted for the iPad or not.
When I created the second UIViewController object, I checked the Targeted for iPad option. Now, my toolbar is styled with a grey tone.
The lesson learned is obvious-- if you want consistency in the default style of your objects that you pull from the IB Toolbox, be sure to create your UIViewControllers, specifically targeted for the iOS device. If you've made the same mistake that I have, follow the linked question above for how to revert your UIViewController and Xib file to the other style of View Controller.
I've been banging my head with this issue for the last two days. Googled a lot but wasn't able to find the answer yet, so I decided to request some help here. Let's see if I get any luck.
I'm coding a reusable control that consists of an UIView with a variable number of customized UIButtons. I implemented initWithFrame:, initWithCoder: and drawRect: where the buttons (which are built prior to drawing) are actually added to the view. Everything is done programmatically since the UIButton content should be supplied when using the control, so there's no XIB for this UIView.
This UIView, let's call it CustomizableBarButton is then used in an UIViewController, let's call it MyTestViewController with a view on it, let's call it customizableBarButtonView.
MyTestViewController's GUI was set on IB where an UIView was tied to customizableBarButtonView (the class was matching accordingly).
MyTestViewController's is a pretty standard class except for the viewWillAppear: that initializes the buttons and passes them to the CustomizableBarButton along with some other options.
The issue is that everything works perfectly...except for the first time!
I mean, when I run the app on the simulator (I haven't tried it on the iPhone yet but I strongly believe that it's not an hardware issue) the MyTestViewController shows the customizableBarButtonView background but not the buttons. Now when you click on the place where a button should be all the buttons suddenly appear!
I'm puzzled since the CustomizablebarButton drawRect: runs before the strange "click n'appear" effect and the buttons are actually added to the subview.
Another hint that my help: if you don't click on the buttons (so you still got no buttons yet) but rotate the device they will also appear as if by magic!
It is probably something very simple but I'm missing it and I'm going nuts...
Can someone lend a hand on this, please?
Thanks in advance!
You said you're adding the buttons in drawRect:. Don't do that. You need to add the buttons in your init methods.
I created a UIScrollView.
I set up the dimensions and then I am trying to add UILabels.
However the labels are all white text (annoying because I have to change the property per label).
Is there a way to make all labels (new ones that are dragged from IB to the view) have a default text color of black?
Edited to match comments
I want to use IB as much as I can. Therefore I want to drag UILabel from the Library palette to the UIView. When I do this, the UILabel is set to white (default). I want the default color to be Black. I know I can do this programatically but I am trying to avoid that unless I really really need to.
There's no easy way to do exactly what you want. But what you can do is create a label with the properties you want, store it somewhere on the drawing board but not in the view, then duplicate it each time you want a new label instead of dragging on a new one. You can duplicate easily using option+drag.
I think the short answer is "no, there's not an easy way to do what you're describing."
The easiest way I can think of would be to create all your UILabels (with the default setting of white text), then control-click them all and set their text color all at once – all the other ways are less convenient, or would essentially require that Apple open-source Xcode or UIKit so that we can get at their internals.
Yes, there is a way. You could loop the subviews of the target view such as:
UIView * targetView;
[...]
for(id subView in targetView.subViews){
if([subView isKindOfClass:[UILabel class]]){
[subView setBackgroundColor:clearColor];
}
}
why do the labels have to come from the object library? You could get the functionality that you want by dragging only one UILable from the library to your view set all the properties to the defaults that you want and hit copy(command+c) once. Now you can paste(command+v) your UILabel with the special property values as many times as you want, IBActions and outlets will also be retained in the copys.
If you plan to tweak more involved properties than font color and size, then I would suggest a more custom approach that will require only minimul coding before you do the bulk drag and drop work in IB.
Subclass a UILable in Xcode, set all of your properties just once in a simple return method and than call this method from both "init" and "awakeFromNib" Now go back to IB and do all your drag/dropping making sure that the labels are of your subclass.
However, it is my opinion that if you are doing this a lot, especially if you will be doing something similar again in the future, you will save a substantial amount of time and energy to implement this "label factory" in code. Its likely less code than you are imagining it will be and the kicker is that you can reuse it in the next app. anyway thats my 2cents, Good Luck