How to reference a UILabel that was added through code so I can update position when iPad is rotated? - ios

I added a UILabel subview using code. When the user rotates the iPad, I want to be able to tell that UILabel to shift its position to accomodate the new screen orientation.
I think I need to put my code in the willAnimateRotationToInterfaceOrientation function.
I want to be able to get at my UILabel and I see sample code that looks like the following to retrieve a reference to a subview:
UILabel *myLabel = (UILabel *) [self.subviews objectAtIndex:0];
How do I know what index my UILabel is at? The sample code seems to know that their subview is the first one (index 0).
Is there a way for me to find out what my UILabel's index is?
Is there another way to keep a reference to this UILabel that I create in code? If I made myLabel a variable of the class, will I be able to reference

Generally, in your UIViewController, you'd have an instance variable that was a pointer to your UILabel. Then you can access it anywhere in your controller's code.

Either have it in an instance variable (I like this, because it allows you to give nice names to your views), or set its tag property so you can find it again via [self.view viewWithTag:myTag] (the tag is just a number you assign to the view for exactly the purpose of finding it later).

Yet another possibility is not to do this, but instead set an autoresizingMask so it (for example) sticks to the upper left corner.

Related

Clear Label text used in Storyboard

Wondering if anyone know hows to complete the following...
In a Storyboard I set my Labels with dummy text, they are not Static text. For example 'User1 Username'.
What I would to know if there is a setting to clear the value of this label when it is loaded by the view. I have some other code that runs off and collects the relevant information. However, it might take a few seconds so a HUD is shown to the user whilst it loads.
Of course in the background of the HUD you can see the example text shown. I know in viewDidLoad I could simply clear all the label texts setting them back to #"", but is there no setting in the storyboard or anything for this?
You can use User Defined Runtime Attributes to achieve this. Simply set "text" attribute for any UILabel, UITextField or UITextView to get what you want:
KVC and runtime attributes are really powerfull when working with Storyboard (e.g. did you know that you can set "layer.cornerRadius" attribute to any UIView to get rounded corners?).
Unfortunately, there is no other way to do it.
You would have to set the text of the UILabel manually in the ViewDidLoad method:
- (void)viewDidLoad
{
[super viewDidLoad];
self.myLabel.text = #"";
}

Issue with overlapping text: iOS7

I normally post source code and examples of UI but I think its more related to an iOS7 change and I cant see it being a code bug (yet). I would have to post so much code and UI that it would be counter productive. So here is my best non-visual description:
Since upgrading a project to iOS7 I am finding that if I put call to change a UILabel or calling setText of a UIButton in a ViewDidAppear or ViewWillAppear it puts the new text right on top of the old text.
Since developing for iOS I have never had to do anything different. If I do this:
lblMyHours.text = #"12";
It shouldnt just throw that on top of my existing label.
This especially happens inside of a UITableView where I have created an iVar for a UILabel thats in a UITableViewCell. If a user makes an adjustment to a value after clicking on a cell (it takes them to a detail screen to edit), when I pop back I have it recalculate in ViewDidAppear. In that recalculating I am resetting a label like the above. But it doesnt clear out the old.
You might be adding a new label every time you return a new cell.
You should just replace the text of the current label instead.
There are two way to achieve this, one you are already doing and as #Guilherme rightly pointed out. The other way is to create a custom tableview cell and put the UILabel property in there. As for the viewDidAppear scenario, you can create a uilabel in ther .h file (in the #interface declaration) and then initialize it in ViewDidLoad method and simple use in ViewDidAppear method without having to declare it again.
I would suggest that you follow the way I described for ViewDidAppear issue, and for the UITableView issue, search for UILabels in subview of the cell everytime cellForRowAtIndex method is called and remove it from the subview, something like this before adding a new label
for(UIView *view in cell.subviews)
{
if([view isKindOfClass:[UILabel class]])
{
[view removeFromSuperview];
}
}
Hope this helps.

Single Tapping not being detected on dynamically created uibuttons

It was necessary to create a subclass of UIButton, lets call it subButton. These subButtons are instantiated one by one and dynamically added to an UIScrollView object.
Unfortunately the subButtons aren't reacting as expected. After scrolling away from the first dynamic generated subButtons and then returning back to them. They loose their reactivity to single tapping. I can not explain this behaviour. Can somebody explain why its behaving this way?
Many thanks.
Source code
self.subButton = [[SubButton alloc]initWithFrame:CGRectMake(69.5, y, 201, 114)];
[self.subButton setBackgroundColor:[UIColor blueColor]];
self.subButton.imageData = imageData;
self.subButton.videoPath = videoPath;
self.subButton.vidIndex = _indexVideo +1;
[self.subButton drawVidPreview];
[self.subButton setTag:(_indexVideo +1)];
[self.subButton addTarget:self action:#selector(handleSingleTap:) forControlEvents:UIControlEventTouchUpInside];
[self.videoScroll addSubview:self.subButton];
[_videoPreviews addObject:self.subButton];
The subButton method drawVidPreview adds some subviews to itself.
Do the buttons not respond at all, or just not to single-tap? That might help us help you.
If they don't respond at all, I would check your view hierarchy to make sure no other view (perhaps invisible) are sitting above your buttons. Or, perhaps are the buttons not being added to the parent view you think?
Please make sure you are not adding the same UIGestureRecognizer instance to all of the UIButtons, instead for each UIButton you need to add a separate instance, however all gesture instance can point to the same target.
At last, i could solve the problem. The reason why the first subButtons did not respond to single tapping with UIControlEventTouchDown is because the uiScrollview content offset was set to a negative y value. This first of all was not necessary and was done out of pure laziness. I corrected it by giving it a positive value.
So my conclusion is, if you do not set the content offset or content size of the scrollView correctly, some dynamically added buttons to the scrollView might not respond to tapping appropriately. This is even the case if all Buttons are placed completely on a uiScrollview object.
This I could confirm by playing around with the content size of the uiScrollview instance too. I changed size of the y value of uiScrollviews instance just by few points and then some of the last buttons did not respond to tapping anymore.
Just by increasing the content size of the y value again, made the buttons responsive again.

UIButton modifying titlelabel seems to change its frame

Something strange is happening. Basically, I am trying to recreate the messaging app. So when I am trying to get the Send button to change from Grey to blue when the user has typed in at least 1 character.
The problem comes when I am trying to change titleLabel, the button will disappear. Later I found out it reverts back to the old position (when the keyboard it not shown).
Why does it do this? If I do not modify the titleLabel everything works as usual. However, if I do, the UIButton goes back to the original location. If you need any sample code let me know, but I am not sure what to put on here as it's just [self.button.titleLabel setTextColor: [UIColor blueColor]; in the UITextViewdidChange but it's acting strange.
Thanks!
Alan
You might be fighting against auto-layout. I saw similar behavior, and someone answered my question here: Why does UIButton resize when I access titleLabel property?. Basically, I was suggested to forego auto-layout completely or only use auto-layout (never set frames programmatically).
Well as mentioned here by others, you might be "fighting" with auto-layout. You do not have to ditch auto-layout, you could just bind the NSLayoutConstraint to an IBOutlet property, and update the constraint. If you do not have a constraint, then one is created automatically for you - you should create one manually and attach it. If it is created in code, the find it by code and save a reference to it.
You could also go back to the simpler AutoResizing, which was there before auto-layout (and is not deprecated, yet).

UIScroll and its nested elements

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

Resources