iphone:Pop up button in UIWebView - iphone

I want to put pop up button like Email in UIWebView.In my app i have created ebook
in webView now whenever i click(long press) on index page link it will create the pop up
window with open and copy button as shwon as below:
Like this i want to put another button like Email and Print.How to create another button in pop up window in WebView?Thanks in advance!

The popup you refer to is called a UIMenuController. You can access the [UIMenuController sharedMenuController] method to get the menu controller. You can then add your own UIMenuItems to the menu controller.
UIMenuItem* myBtn1 = [[[UIMenuItem alloc] initWithTitle: #"Button 1" action:#selector( onButton1: )] autorelease];
UIMenuItem* myBtn2 = [[[UIMenuItem alloc] initWithTitle: #"Button 2" action:#selector( onButton2: )] autorelease];
UIMenuController* mc = [UIMenuController sharedMenuController];
mc.menuItems = [NSArray arrayWithObjects: myBtn1, myBtn2, nil];
Now implement the methods
- (void) onButton1: (UIMenuController*) sender
{
}
- (void) onButton2: (UIMenuController*) sender
{
}
For more detail refer apple's Doc.
Edit
you can implement Long Gesture
UILongPressGestureRecognizer* gr = [[[UILongPressGestureRecognizer alloc] initWithTarget: self action: #selector( onShowMenu: ) ] autorelease];
[_myview addGestureRecognizer: gr];
- (void) onShowMenu: (UIGestureRecognizer*) sender
{
[sender.view becomeFirstResponder];
UIMenuController* mc = [UIMenuController sharedMenuController];
CGRect bounds = sender.view.bounds;
[mc setTargetRect: sender.view.frame inView: sender.view.superview];
[mc setMenuVisible: YES animated: YES];
}

you can create a View Controller, and in the view controller's .xib file you can add your buttons.
then you can call that viewcontroller in the UIPopover..and load that view controller in it.
Now as you want to show this popover in the index page only, for this you have to keep a track of pages like pages form 1-3 are of index page so the popOver should be seen on that page.
and when you click on the index link you can use the webView delegate function i.e
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
under this function you can apply your logic and initiate the popover that will be seen

Related

How to navigate the view in iphone programming?

In my appController's ViewDidLoad, I have done some thing as below
- (void)viewDidLoad
{
self.overlayViewController =
[[[OverlayViewController alloc] initWithNibName:#"OverlayViewController" bundle:nil] autorelease];
// as a delegate we will be notified when pictures are taken and when to dismiss the image picker
self.overlayViewController.delegate = self;
self.capturedImages = [NSMutableArray array];
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
// camera is not on this device, don't show the camera button
NSMutableArray *toolbarItems = [NSMutableArray arrayWithCapacity:self.myToolbar.items.count];
[toolbarItems addObjectsFromArray:self.myToolbar.items];
[toolbarItems removeObjectAtIndex:2];
[self.myToolbar setItems:toolbarItems animated:NO];
}
}
I have two methods as below,
- (IBAction)cameraAction:(id)sender
{
[self showImagePicker:UIImagePickerControllerSourceTypeCamera];
}
- (void)showImagePicker:(UIImagePickerControllerSourceType)sourceType
{
if (self.imageView.isAnimating)
self.imageView.stopAnimating;
if (self.capturedImages.count > 0)
[self.capturedImages removeAllObjects];
if ([UIImagePickerController isSourceTypeAvailable:sourceType])
{
[self.overlayViewController setupImagePicker:sourceType];
[self presentModalViewController:self.overlayViewController.imagePickerController animated:YES];
}
}
Now as I click the button, the method will launch the class showing custom view, I want to call this without clicking the button, what should I do ?
I wrote the button coding directly in ViewDidLoad, but not working at all
This code, I took from apple's documentation as example
Help !
If I understand correctly, you are wanting to show a view?
If so you could push using:
[self.navigationcontroller pushviewcontroller:YOURVIEWCONTROLLER animated:YES];
Or you could present it using:
[self presentModalViewControllerpushviewcontroller:YOURVIEWCONTROLLER animated:YES];

how to show UIMenuController to UIBarButtonItem

How to show UIMenuController under UIBarButtonItem when click it?
Assume your UIBarButtonItem has been connected to:
-(void)buttonClicked:(UIBarButtonItem*)sender event:(UIEvent*)event;
Then paste these codes into your view controller:
-(void)buttonClicked:(UIBarButtonItem*)sender event:(UIEvent*)event{
[self becomeFirstResponder];
/*get the view from the UIBarButtonItem*/
UIView *buttonView=[[event.allTouches anyObject] view];
CGRect buttonFrame=[buttonView convertRect:buttonView.frame toView:self.view];
UIMenuController *menuController = [UIMenuController sharedMenuController];
UIMenuItem *resetMenuItem = [[UIMenuItem alloc] initWithTitle:#"Menu Item" action:#selector(menuItemClicked:)];
NSAssert([self becomeFirstResponder], #"Sorry, UIMenuController will not work with %# since it cannot become first responder", self);
[menuController setMenuItems:[NSArray arrayWithObject:resetMenuItem]];
[menuController setTargetRect:buttonFrame inView:self.view];
[menuController setMenuVisible:YES animated:YES];
[resetMenuItem release];
}
- (void) copy:(id) sender {
// called when copy clicked in menu
}
- (void) menuItemClicked:(id) sender {
// called when Item clicked in menu
}
- (BOOL) canPerformAction:(SEL)selector withSender:(id) sender {
if (selector == #selector(menuItemClicked:) /*|| selector == #selector(copy:)*/ /*<--enable that if you want the copy item */) {
return YES;
}
return NO;
}
- (BOOL) canBecomeFirstResponder {
return YES;
}
The key is to return YES for canBecomeFirstResponder and canPerformAction.
Here's the sample project if you need it.
These codes are actually come from other posts in stackoverflow, I just combined them.
Figure out UIBarButtonItem frame in window?
How to get UIMenuController work for a custom view?

iOS: Pop-up menu does not behave in accordance with first responder set

I have several objects inheriting UIView in my application that are tracking taps on them and presenting Copy/Paste pop-up if they contain some specific data. When pop-up is presented I change the appearance of the object as well.
This is how it is implemented:
- (void)viewDidReceiveSingleTap:(NSNotification *)n {
MyObject *mo = (MyObject *)n.object;
[mo becomeFirstResponder];
UIMenuController *menu = [UIMenuController sharedMenuController];
[menu update];
[menu setTargetRect:CGRectMake(...) inView:mo];
[menu setMenuVisible:YES animated:YES];
}
MyObject class, in turn, defines canBecomeFirstResponder: and canResignFirstResponder: as always returning YES. becomeFirstResponder:, resignFirstResponder:, and canPerformAction:withSender: is also defined accordingly (this is where I change the appearance of the object).
This is what goes wrong:
I tap object 1. The method viewDidReceiveSingleTap: above is getting called, and the object's canBecomeFirstResponder: and becomeFirstResponder: are getting called too. The pop-up menu is displayed as expected.
I tap another object 2. viewDidReceiveSingleTap: is called again and here's where the trouble starts. First, canResignFirstResponder:, resignFirstResponder: of object 1 are called, but not always, and I can't figure out the pattern. canBecomeFirstResponder: and becomeFirstResponder: of object 2 are called properly, but the pop-up menu does not relocate. It just disappears (though in the viewDidReceiveSingleTap: I clearly call setMenuVisible:YES). In order to make it appear, I have to tap object 2 (or any other) again -- in this case I can see from the debugger that object 2 was set as a first responder, it's just the pop-up that wasn't appearing.
What am I doing wrong? Any clues on relation between pop-up menu visibility and first responder?
The issue is that, when you tap anywhere except on the menu, it does an animated hide of itself. That hide is taking precedence over your animated show. So, if you tap a view to make the menu show, tap anywhere else (either on another one of those views or just anywhere else), and then tap another one of those views, the menu will show every time.
I think there's a good argument to be made for keeping that behavior, because it's the standard behavior that users will expect. But, of course, you have a better idea of what makes sense for your app. So, here's the trick:
[menu setMenuVisible:NO animated:NO];
[menu setMenuVisible:YES animated:YES];
Here's the code I used to try it out:
#implementation MenuView
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor blueColor];
}
return self;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self becomeFirstResponder];
UIMenuController *menu = [UIMenuController sharedMenuController];
UIMenuItem *item = [UIMenuItem alloc] initWithTitle:#"Test"
action:#selector(test)];
NSArray *items = [NSArray arrayWithObject:item];
[item release];
[menu setMenuItems:items];
[menu setTargetRect:self.bounds inView:self];
[menu setMenuVisible:NO animated:NO];
[menu setMenuVisible:YES animated:YES];
}
- (void)test {
NSLog(#"Test!");
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
return action == #selector(test);
}
- (BOOL)canBecomeFirstResponder {
NSLog(#"Can become called");
return YES;
}
- (BOOL)canResignFirstResponder {
NSLog(#"Can resign called");
return YES;
}
- (BOOL)becomeFirstResponder {
[super becomeFirstResponder];
NSLog(#"Become called");
return YES;
}
- (void)dealloc {
[super dealloc];
}
#end

Customize UIMenuController

Hi I want to create a customize bubble menu, like cut/copy/paste menu, in IPhone SDK3.x. I know it is UIMenuController but it is only provide standard cut/copy/past menu. Anyone know how to make a bubble menu similar like this. Any example and code for reference?
1) you need to add custom menu items to the shared UIMenuController:
UIMenuItem* miCustom1 = [[[UIMenuItem alloc] initWithTitle: #"Custom 1" action:#selector( onCustom1: )] autorelease];
UIMenuItem* miCustom2 = [[[UIMenuItem alloc] initWithTitle: #"Custom 2" action:#selector( onCustom2: )] autorelease];
UIMenuController* mc = [UIMenuController sharedMenuController];
mc.menuItems = [NSArray arrayWithObjects: miCustom1, miCustom2, nil];
2) you need to implement your handler methods somewhere in the responder chain for the view that will be first-responder when you show the menu:
- (void) onCustom1: (UIMenuController*) sender
{
}
- (void) onCustom2: (UIMenuController*) sender
{
}
3) you optionally need to implement canPerformAction: in the responder chain for the view that will be first-responder when you show the menu:
- (BOOL) canPerformAction:(SEL)action withSender:(id)sender
{
if ( action == #selector( onCustom1: ) )
{
return YES; // logic here for context menu show/hide
}
if ( action == #selector( onCustom2: ) )
{
return NO; // logic here for context menu show/hide
}
if ( action == #selector( copy: ) )
{
// turn off copy: if you like:
return NO;
}
return [super canPerformAction: action withSender: sender];
}
4) if the view you want to present the menu for doesn't already support showing a menu, (i.e. a UIWebView will show a menu when the user does a long-tap, but a UILabel has no built in support for showing a menu), then you need to present the menu yourself. This is often done by attaching a UILongPressGestureRecognizer to the view, then showing the menu in the callback:
UILongPressGestureRecognizer* gr = [[[UILongPressGestureRecognizer alloc] initWithTarget: self action: #selector( onShowMenu: ) ] autorelease];
[_myview addGestureRecognizer: gr];
- (void) onShowMenu: (UIGestureRecognizer*) sender
{
[sender.view becomeFirstResponder];
UIMenuController* mc = [UIMenuController sharedMenuController];
CGRect bounds = sender.view.bounds;
[mc setTargetRect: sender.view.frame inView: sender.view.superview];
[mc setMenuVisible: YES animated: YES];
}
Note, there has to be a view that claims firstResponder for the menu to show.
5) make sure the view you're showing the menu for returns YES/TRUE to canBecomeFirstResponder. For example, if you try to make a UILabel a first responder it will return NO, so you would have to subclass it.
6) that's about it. You may want to resignFirstResponder when the action callback is called - but to do this you'll need to implement logic to discover the firstResponder.
Use the menuItems property on UIMenuController.

how to get around lack of 'add' button in ABPeoplePickerNavigationController?

My app needs to associate instances of a custom class with contact records in the iPhone's AddressBook. Everything's all well and good when I present the ABPeoplePickerNavigationController and allow the user to pick an existing contact. Problem is there's no obvious way to allow a user to easily ADD a contact record if the one they're looking for doesn't already exist in their AddressBook.
How are people getting from ABPeoplePickerNavigationController to ABNewPersonViewController in a way that's easy & intuitive for the user?
You can create a UIBarButton and add it to the UINavigationBar of the ABPeoplePickerNavigationController like so.
peoplePicker.topViewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addPerson:)];
-(IBAction)addPerson:(id)sender{
ABNewPersonViewController *view = [[ABNewPersonViewController alloc] init];
view.newPersonViewDelegate = self;
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:view];
[self.picker presentModalViewController:nc animated:YES];
}
The issue that i came up against was that the ABPeoplePickerNavigationController has a cancel button placed in the rightBarButtonItem slot and I had to update the navigation bar on the
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
I have documented the entire process on my blog with a worked example that should allow you to create a contacts style application similar to that on the iPhone. Hope this helps.
I found Scott Sherwood's approach along with the demo he posted on his site to be very helpful. As one of the commenters on his blog mentioned though, there is a problem with the Cancel button in Edit mode.
I just proposed a fix to Scott's demo, along with a different approach for the Person View Controller at:
http://finalize.com/2013/05/12/using-and-customizing-the-address-book-ui/
My suggestion for the Person View Controller was to put it up manually in the protocol method peoplePickerNavigationController:shouldContinueAfterSelectingPerson: for the ABPeoplePickerNavigationControllerDelegate.
// Displays the information of a selected person
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
ABPersonViewController *view = [[ABPersonViewController alloc] init];
view.personViewDelegate = self;
view.displayedPerson = person; // Assume person is already defined.
view.allowsEditing = YES;
view.allowsActions = YES;
[peoplePicker pushViewController:view animated:YES];
return NO;
}
The only issue here is that the People Picker table view of names is not refreshed automatically after an edit. This can be fixed with the use of an Address Book callback. I show how this can be done in the GitHub project I posted at:
https://github.com/scottcarter/AddressBookPeoplePicker.git
it appears that it is not possible to add a new contact directly from the ABPeoplePickerNavigationController. Therefore, when the user clicks an add button, I am presenting an UIActionSheet with two buttons:
- (void) addContact{
contactMenu = [[UIActionSheet alloc]
initWithTitle: nil
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle: nil
otherButtonTitles:#"Select a contact", #"Add a new contact", NULL];
[contactMenu showInView:self.view];
}
Here is the associated delegate method:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex == 0){
// select an existing contact
ABPeoplePickerNavigationController *peoplePicker = [[ABPeoplePickerNavigationController alloc] init];
peoplePicker.peoplePickerDelegate = self;
[self presentModalViewController:peoplePicker animated:YES];
}
if(buttonIndex == 1){
// add a new contact
ABNewPersonViewController *newPersonViewController = [[ABNewPersonViewController alloc] init];
newPersonViewController.newPersonViewDelegate = self;
UINavigationController *personNavController = [[UINavigationController alloc] initWithRootViewController:newPersonViewController];
[self presentModalViewController:personNavController animated:YES];
[personNavController release];
[newPersonViewController release];
}
if(buttonIndex == 2){
// cancel the operation
[actionSheet dismissWithClickedButtonIndex:2 animated:YES];
}
}