MonoTouch : Can I use a UILabel to show a phone number? - iphone

I need to show a phone number in a view and that when clicked a call is initiated. Currently I'm using an UILabel and I have no idea how to do it.
Is this the correct control? If no which one would be?
If it's the correct one, how can I do it?

An UILabel could be used (kind of showing a link) but an UIButton might be more appropriate.
You can find the code to initiate the code from this question (and answer).
Using a UIButton and the code from above would give you:
var btn = UIButton.FromType(UIButtonType.RoundedRect);
btn.Frame = new RectangleF (10,10,100,200);
btn.SetTitle ("call me", UIControlState.Normal);
btn.TouchUpInside += delegate {
UIApplication.SharedApplication.OpenUrl (NSUrl.FromString ("tel://411"));
};

Related

UIBarButtonItem created using initWithCustomView doesn't trigger action

I'm updating some old code, and to make more room in a toolbar, I'm converting the Buttons from test to images. An example of the new and old code in loadView is this:
// New code, doesn't work.
UIButton *toggleKeyboardBtn = [UIButton buttonWithType:UIButtonTypeCustom];
toggleKeyboardBtn.bounds = CGRectMake( 0, 0, showKeyboardImage.size.width, showKeyboardImage.size.height );
[toggleKeyboardBtn setImage:showKeyboardImage forState:UIControlStateNormal];
UIBarButtonItem *toggleKeyboardItem = [[UIBarButtonItem alloc] initWithCustomView:toggleKeyboardBtn];
[toggleKeyboardItem setTarget:self];
[toggleKeyboardItem setAction:#selector(toggleKeyboard:)];
// Original code, works jut fine.
UIBarButtonItem *setupItem = [[[UIBarButtonItem alloc] initWithTitle:#"Setup" style:UIBarButtonItemStyleBordered target:[UIApplication sharedApplication].delegate action:#selector(showSetupView:)] autorelease];
My new code is copied from Cannot set action on UIBarButtonItem, and I'm fairly certain that I'm not making their mistake since my text button is working just fine.
showSetupView() is in my AppController.m file, and the setup screen appears and disappears as the button is pressed.
toggleKeyboard(), OTOH, is in the same file as the loadView() routine, and currently consists of this code:
//- (void)toggleKeyboard {
- (IBAction)toggleKeyboard:(id)sender {
NSLog(#"Entering toggleKeyboard()...");
hiddenKeyboard = !hiddenKeyboard;
[self prepareToolbarsAndStatusbar];
}
Needless to say, although I see the button-press animation, I never see the NSLog message. And one last observation, made by accident. Changing the setAction selector to this:
[toggleKeyboardItem setAction:#selector(noSuchRoutine:)];
compiles cleanly, possibly indicating that my routine name is being ignored for some reason.
Anyone have any ideas? Thanks.
I found the answer! In button action not responding iphone, it's said that the action and target need to be set on the UIButton, not the UIBarButtonItem. I don't know if that's new with the latest version of Xcode, but I guess it is since other questions (such as the one I mention above) use a different technique. Here's my new code:
UIButton *toggleKeyboardButton = [UIButton buttonWithType:UIButtonTypeCustom];
toggleKeyboardButton.bounds = CGRectMake( 0, 0, keyboardAddImage.size.width, keyboardAddImage.size.height );
[toggleKeyboardButton setImage:keyboardAddImage forState:UIControlStateNormal];
[toggleKeyboardButton addTarget:self action:#selector(toggleKeyboard) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *toggleKeyboardItem = [[UIBarButtonItem alloc] initWithCustomView:toggleKeyboardButton];
//[toggleKeyboardItem setTarget:self];
//[toggleKeyboardItem setAction:#selector(toggleKeyboard:)];
Though its too late, but for future references, I would like to quote apple docs for the method,
- (instancetype)initWithCustomView:(UIView *)customView;
The bar button item created by this method does not call
the action method of its target in response to user interactions.
Instead, the bar button item expects the specified custom view to
handle any user interactions and provide an appropriate response.
Did you try
-(void)toggleKeyboard
and
[toggleKeyboardItem setAction:#selector(toggleKeyboard)]; without :
and it made any difference? Is the method declared in the interface file?

Attempts to tap a UIButton in a UITableViewCell using UI Automation fail with "could not be tapped"

I have an iPhone app that I'm testing using UI Automation.
I have a button in a UITableViewCell but when I try to tap on it using UI Automation I get the following error.
Script threw an uncaught JavaScript error: target.frontMostApp().mainWindow().scrollViews()[0].elements()[element_name].tableViews()[0].elements().firstWithPredicate(name contains[c] 'Brooklyn').elements()["detailsButton"] could not be tapped
I have enabled accessibility on the button in Interface Builder and assigned the accessibility label (and identifier) "detailsButton". I can retrieve the button element and have verified that it is valid. I just can't tap it for some reason.
The UIButton is a round rectangular button with user interaction enabled. Thanks for any feedback.
You can alloc the UIButton except using round rect button. And also you can set target action of button in your controller class where table view delegate methods are presents.
Try asserting first if the button exists, use tuneup_js for easy assertions.
Then assert if the button is enabled.
Have you tried:
target.frontMostApp().mainWindow().scrollViews()[0].elements()[element_name].tableViews()[0].**cells()**.firstWithPredicate("name contains[c] 'Brooklyn'").elements()["detailsButton"]?
Also post another picture which shows the UIATableCell expanded where the detailsButton exists.
You have to use ButtonType=Custom
I don't know why you are using UI Automation. But as much I know about adding UIButton in a tableviewcell-
1) just add UIButton in UITableViewCell.
2) set UIButton's tag value and add target to that button.
3) In the target button method, you can get the UIButton object and do your stuff over there..
Hope this helps you out.
but=[UIButton buttonWithType:UIButtonTypeCustom];
You must use a custom button type.
I have met the same problem. After I added the delay it works.
UIATarget.localTarget().delay(1);
You can dispatch a tap event over the entire window:
function tap_from_window(elem) {
var mainWindow = target.frontMostApp().mainWindow();
var elemRect = elem.rect();
var windowRect = mainWindow.rect();
var xPos = (20 + elemRect.origin.x) / windowRect.size.width;
var yPos = (50 + elemRect.origin.y) / windowRect.size.height;
mainWindow.tapWithOptions({tapOffset:{x:xPos, y:yPos}});
}
var target = UIATarget.localTarget();
var window = target.frontMostApp().mainWindow();
var tableView = window.scrollViews()[0].elements()[element_name].tableViews()[0];
tap_from_window(tableView.elements().firstWithPredicate(name contains[c] 'Brooklyn'))
Like many things related to iOS, I have no idea why the element cannot be tapped directly. I adapted the above function from the code in this post: scrollToVisible error while testing on a device, UIAutomation

how to add textfield and button programmatically?

I have a tableView and I want to apply search facility on tableView. For that I require textField and search Button but I don't know how to create these programmatically. so plz tell me how to create these two tools.
thanx.
Try with the following link which describes for asynchronous scrollbar example
http://blog.patrickcrosby.com/2010/04/27/iphone-ipad-uisearchbar-uisearchdisplaycontroller-asynchronous-example.html
But you can also refer the previous post
UISearchBar Sample Code
For more methods of implementing and getting results as you type, go to apples document and refer UISearchBarDelegate Protocol Methods
Here's the documentation for UITextField and UIButton. You might also find UISearchBar useful, which incorporates both a text field and a button.
Add your views to the table view's header view.
You have a table delegate tableview:cellForRowAtIndexPath. In this delegate add the following code.
//Suppose you want to add textfield and button at the first row
if(indexPath.Row == 0)
{
UITextField *txtSearch = [UITextField alloc] initWithFrame:CGRectMake(0,0,150,35)];
UIButton *btnSearch = [UIButton buttonWithType:UIButtoTypeCustom];
btnSearch.frame = CGRectMake(160,0,50,35);
[[cell contentView] addSubView:txtSearch];
[[cell contentView] addSubView:btnSearch];
}
Also You can add event for button like
[btnSearch addTarget:self action:#selector(eventName) forControlEvents:UIControlEventTouchUpInside];
Thanks

route-me marker label with UIButtonTypeDetailDisclosure-Button - Button isn't clickabel

I've got a problem with the route-me framework and marker labels. I'm trying now about 5 hours with no luck and searched almost every forum topic on the web about this.
I want to add a marker label with a UIButtonTypeDetailDisclosure-Button on it.
When I add the Button to the UIView that should be the label I can't click on the Button.
My code is as follows:
- (void)tapOnMarker:(RMMarker*)marker onMap:(RMMapView*)map {
UIView *frame = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
UIButton *button = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
button.frame = CGRectMake(0, 0, 34, 34);
button.enabled = YES;
button.userInteractionEnabled = YES;
[button addTarget:self action:#selector(markerLabelButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[frame addSubview:button];
[marker setLabel:frame];
[marker showLabel];
}
-(void)markerLabelButtonPressed:(id)sender {
NSLog(#"pressed");
}
I hope anyone may help me with this. Thanks :)
I you need any more information please let me know!
Ok finally i managed to solve the problem.
Maybe it's a little dirty workaround, but anyway it's working ;)
I modified the route-me framework and added a method called
- (void) tapOnLabelForMarker: (RMMarker*) marker onMap: (RMMapView*) map onLayer:(CALayer *)layer;
In RMMapView.m I added the following Lines in Line 584:
else if ([superlayer superlayer] != nil && [[[superlayer superlayer] superlayer] isKindOfClass: [RMMarker class]]) {
if (_delegateHasTapOnLabelForMarker) {
[delegate tapOnLabelForMarker:(RMMarker*)[[superlayer superlayer] superlayer] onMap:self onLayer:superlayer];
}
}
Now then the disclosurebutton is tapped this part of the code is executed and my method is called.
When any other area of the marker label is tapped the
- (void) tapOnLabelForMarker: (RMMarker*) marker onMap: (RMMapView*) map;
method is called.
Hope this helps anyone else ;)
This issue is resolved by this pull request https://github.com/route-me/route-me/pull/161.
It has been merged in route-me code on feb 21st 2012.
Take a look to this thread in the route google groups list:
http://groups.google.com/group/route-me-map/browse_thread/thread/343cb3ebfd9480e3
someone was answered with some code for marker "balloon" labels that uses a close button.
I had trouble with this solution, and I don't want to be one of those people who tell you to do it differently because you may have good cause to do things the way you are doing them.
I took this initial approach, then via another thread I realized: If I only want to have one callout at a time, I can just manage him as a subview of the mapView and use the helper methods of the mapView.markerManager. A RMMarker object has a data pointer which you can use to fill in the contents of your callout bubble.
This saved me a lot of time and I have a satisfactory solution that doesn't get that dirty at all.

How can I safely memory manage a button that I want to remove from the UI?

I'm making an app that is kinda like iBooks. There is some stuff on the screen, each item represented by a small thumbnail. I want the user to be able to delete the items much like when you tap the "Edit" button in iBooks - an X comes up, and the item is deleted. I'm using the delegation pattern to handle all of this, so here is some code:
// Button is created in CustomView.h class
UIImage *deleteImage = [UIImage imageNamed:#"delete.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
self.deleteButton = button;
[self.deleteButton setImage:deleteImage forState:UIControlStateNormal];
[self.deleteButton addTarget:self action:#selector(deleteIt) forControlEvents:UIControlEventTouchUpInside];
// Here's what's called when the delete button is pushed
- (IBAction)deleteMap {
[self.customViewDelegate itemWasDeleted:self];
}
// And here's the implementation of that method, in a View Controller
- (void)itemWasDeleted:self:(CustomView*)customView {
// delete domain object
// . . .
[self.collectionOfCustomViews removeObject:customView];
[customView removeFromSuperview];
}
The problem with this code is that I get a Bad Access Exception. Via NSZombie, looks like this:
* -[UIButton _unhighlight]: message sent to deallocated instance 0x5f4a740
I guess what's happening is that when my target-action implementation is called, it's not yet safe to release the button, as I'm doing in my delegate method. So my question is, what's a better approach to doing this so that may app doesn't crash? I'd like to know the cleanest approach possible.
If collectionOfCustomViews was the only object retaining customView then you released it when you removed it, so it can't respond to removeFromSuperview.