I have many UIButton elements on my MKMapView. When the user clicks on a button I get a showDetails notification. But how do I tell which button the user clicked on? The only hack I know of is to pass in the tag value which is an integer. Surely there must be a more elegant way. I tried subclassing UIButton but since it is a cluster, I cannot subclass it and use all of theUIButtons existing functionality.
Thanks
Deshawn
tag is a good way to identify you can also use current title to differentiate if all buttons have different titles. here is a code snippet
[[button currentTitle] isEqualToString:#"your desired string"];
But I prefer use tags.
Related
I'm trying to set the text of the "Retake" and "Use" buttons on the PLUICameraViewController. I've programmatically navigated through the view hierarchy and found a few UIButtonLabel objects. Logging the text of these shows what I expect: "Retake", "Cancel" etc. However setting the text doesn't work. The buttons just keep their original text. Here's what I've tried:
if (q is a subclass of UIButtonLabel)
if ([q respondsToSelector:#selector(setText:)])
[q performSelector:#selector(setText:) withObject:#"zzz"];
The code runs w/o crashing. Also respondsToSelector is returning YES. How can I make the text on the buttons update?
By the way I'm aware of other approaches involving custom buttons, my own views etc. I'm really curious from an Objective-C/runtime/iOS perspective why the above code doesn't work.
Also note I'm doing this in
navigationController:willShowViewController:viewController:animated:
In this case, I don't think it's an issue of Private APIs, per se. This is just the way UIButton works.
Yes, the title of the button is a UILabel, and in practice, it is probably/currently an instance of the private class UIButtonLabel. But, the way Apple intends for you to change the title text is to use the methods in UIButton itself:
[self.button setTitle: #"newTitle" forState: UIControlStateNormal];
[self.button setTitle: #"newTitle" forState: UIControlStateSelected];
instead of trying to drill down into the button's subview heirarchy, find a button label, and call setText:.
Here's the relevant API documentation
As to why it doesn't work, I suppose that's because Apple wants it that way.
For one, changing a button's title is expected to be a normal use case. So, for convenience, they probably wanted to give you an easy method to call, directly in the UIButton interface. If they forced you do drill down into the view hierarchy, not only would you have to write more code, but it makes it a little harder for Apple to change the underlying implementation of a button. They may want to preserve the ability to change it later, and for that, it's better for them to keep some sort of wrapper APIs at the UIButton level.
Also, if you directly change the text on the button label, you are circumventing their design, where the label text depends on the button state (e.g. normal, highlighted, selected, etc.) Even though most people probably use the same button text for all states, the design allows for state-dependent text, and therefore, hiding the underlying UIButtonLabel helps enforce this design.
That's my guess as to their motivation.
So, to enforce this, it's entirely possible that in their implementation of UIButtonLabel setText:, they decline to update the text after the button has been initialized. After that, you have to use the setTitle:forState: method.
I have a text with multiple lines but at the end I want to add the phrase "more..." if the user press the more... word than the system it suppose to display the rest of the paragraph.
How can I do that?
one way is: use a UILabel to display a short text
put a UIButton under that with "show more" make settings to button to look like a UILabel
catch the action of the button, and remove the button and display a multines text and change the size of the UILabel.
This isn't the right approach for novice programmers, I hope I have helped with an idea.
You could use a UITextView that contains the limited text and add a UITapGestureRecognizer that when tapped, removes the gesture and adds text to the textview.
There is no particularly easy way, built-in way to do it. If you want to implement it yourself, your best bet is to use a UITextView instead of a UILabel. UITextView conforms to the UITextInput protocol, so when you detect a tap on the text view, you can use closestPositionToPoint: and related messages to figure out which part of the string was tapped.
Instead of doing it yourself, you could use TTTAttributedLabel or OHAttributedLabel. Both of these have built-in support for detecting taps on links. I haven't used either, so I can't advise you on which is better. There are probably other free solutions available, but those were easy to find.
I'm still a noob to iPhone development so sorry for the dumb question. I'm creating an app that has a custom numeric keyboard. I have an IBAction 'buttonDigitPressed' that when a digit is pressed it will simply add the digit to a UILabel. Now I have another label that I wish to do the same yet I'm not sure how to gain 'focus' of that particular label. I placed an invisible button over the second label so when pressed hopefully I can call an action to switch the keyboard from the first label to the second label. Yet I have no clue how to accomplish this. Any help would be greatly appreciated!
First of all, having to put an invisible button over the UILabel is skanky. If you want the user to be able to tap a number to mean "next time I hit a digit, append its value to this number", you'll probably be happier if you just use a UIButton right from the start. You can make a UIButton that looks pretty much like a UILabel (i.e. it has no border or background color). To set a UIButton's title in code, call setTitle:forState: with the UIControlStateNormal state. So now you've got tappable numbers, i.e. these UIButtons.
Okay, so now let's pretend you've got, say, three UIButtons. You need to use an instance variable here. So, each button will have an action - let's say doButton:(id)sender. So doButton will store the value of sender (the button that was just pressed) in the instance variable. Now your buttonDigitPressed action just looks in that instance variable to learn which button to append to. That's part of the power of instance variables - they give a method in a class a place to store a value where another method in the same class can get at it.
I've got an Custom UIButton. It's got
a "static" background image
a variable text (the Title) which gets set in the code
Now I would like to add an icon (UIImage/UIImageView) inside the button on the left of the text. (I use the indent to move the text slightly to the right). Is there an easy way of adding that icon (and referencing it from code, so I can change it) or would you recommend creating a completely new button e.g. based on a UIView? (e.g. a view, that responds to touches)?
I'm just trying to get a feel for what the best approach would be for this. Any experience?
Two ways:
I prefer doing this by subclassing a UIView and (as you mention) implement the UITouch-responder methods. You're also able to override drawRect: what I really like because it makes your app soooooo much faster!
Since UIButton is a subclass of UIView, you can add a UIImageView to your button by using addSubview:. If you save it in your main-class (#property (...) UIButton *button) you can always access it by calling [self button]. You can also subclass your UIButton and add this #property. That's up to you.
It's totally up to you. However I prefer the first way!
I am looking for some code to make a Menu appear next to a button when it is clicked.
What code would I need for this?
Sorry if this sounds a bit vague.
Why not use NSPopUpButton?
NSPopupButton was my first thought as well. It's how apps with the "action gear" buttons accomplish their menus.
If you do have something else in mind though, look at NSMenu's +popUpContextMenu:withEvent:forView:. Just hook an action method up to your button, create an NSMenu and populate it with NSMenuItems, and send it to this method along the the current event from NSApplication's currentEvent getter.
If you really need to roll this yourself, rather than using one of the built-in controls that shows a menu, you can create an NSPopupButtonCell and use that to show the NSMenu:
NSPopUpButtonCell *popupCell = [[NSPopUpButtonCell alloc] initTextCell:#"" pullsDown:YES];
[popupCell setMenu:yourMenu];
[popupCell trackMouse:event inRect:[yourButton bounds] ofView:yourButton untilMouseUp:YES];
[popupCell release];
You'd want to adjust the pullsDown:, inRect:, and ofView: arguments as necessary to position the menu the way you want.