UIMenuController doesn't show in a second UIViewController - iphone

I have two UIViewController, one is the main and from this trough a button you can go to the second. In SecondView.m I have the following code:
- (IBAction)showpopup:(id)sender {
[self becomeFirstResponder];
UIMenuController *sharedController = [UIMenuController sharedMenuController];
UIMenuItem *x2 = [[UIMenuItem alloc] initWithTitle:#"2x2" action: #selector(mat)];
UIMenuItem *x3 = [[UIMenuItem alloc] initWithTitle:#"3x3" action: #selector(mat)];
UIMenuItem *x4 = [[UIMenuItem alloc] initWithTitle:#"4x4" action: #selector(mat)];
UIMenuItem *x5 = [[UIMenuItem alloc] initWithTitle:#"5x5" action: #selector(mat)];
NSArray *menuArray = [NSArray arrayWithObjects: x2,x3,x4,x5, nil];
CGRect drawRect = [sender convertRect:[sender bounds] toView: self.view];
[sharedController setTargetRect:drawRect inView: self.view];
[sharedController setMenuItems:menuArray];
[sharedController setMenuVisible:YES animated:YES];
[sharedController setMenuItems: nil];
}
-(BOOL)canBecomeFirstResponder{
return YES;
}
-(int)mat:(id)sender{
return 0;
}
The Button is linked as "touch up inside", but when I run the UIMenuController doesn't show up.
The exact same code works in the main UIViewController.
Thanks

If I am not missing anything, I think you should, e.g., add your sharedController.view as a subview to your mainController.view, e.g. (assuming that `showpopup is defined in your main controller):
- (IBAction)showpopup:(id)sender {
[self becomeFirstResponder];
UIMenuController *sharedController = [UIMenuController sharedMenuController];
...
[sharedController setMenuItems:menuArray];
[sharedController setMenuVisible:YES animated:YES];
[sharedController setMenuItems: nil];
[self.view addSubview:sharedController.view];
}
or you could present modally your sharedController (replace the addSubview line above):
[self presentViewController:sharedController animated:YES completion:nil];
In any case, it seems to me that the "presenting" bit is missing.

Related

Change label title of menu in UICollectionView

I would like to use the same look and feel as the menu bar when clicking on a uicollectionviewcell as looks here:
However, instead of cut I would like to write move
Is it possible? I saw some answers - but they all asked to implement my own UIActionSheet - but I would like it to look like a menu and not an action sheet
Is it possible?
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(showMenu:)];
longPressGesture.minimumPressDuration=0.4;
[longPressGesture setDelegate:self];
[self.collectionCell addGestureRecognizer:longPressGesture];
- (void) showMenu:(UILongPressGestureRecognizer *)gestureRecognizer
{
if ([gestureRecognizer state] == UIGestureRecognizerStateEnded) {
UIMenuController *menuController = [UIMenuController sharedMenuController];
UIMenuItem *menuItem1 = [[UIMenuItem alloc] initWithTitle:#"Cut" action:#selector(copyAction:)];
UIMenuItem *menuItem3 = [[UIMenuItem alloc] initWithTitle:#"Paste" action:#selector(pasteAction)];
CGPoint location = [gestureRecognizer locationInView:[gestureRecognizer view]];
[menuController setMenuItems:[NSArray arrayWithObjects: menuItem1, menuItem1,nil]];
[menuController setTargetRect:CGRectMake(location.x, location.y, 0, 0) inView:[gestureRecognizer view]];
[menuController setMenuVisible:YES animated:YES];
[self becomeFirstResponder];
}
}
In case anyone else needs:
here is the correct answer from #Nilz11:
Add to ViewDidLoad
UIMenuItem *menuItem = [[UIMenuItem alloc] initWithTitle:#"Edit" action:#selector(editMe:)];
UIMenuItem *menuItem2 = [[UIMenuItem alloc] initWithTitle:#"Move" action:#selector(moveMe:)];
UIMenuItem *menuItem3 = [[UIMenuItem alloc] initWithTitle:#"DeleteMe" action:#selector(deletePlate:)];
[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObjects:menuItem,menuItem2,menuItem3, nil]];
Add delegate methods
-(BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender{
if (action == #selector(editMe:) || action == #selector(moveMe:) || action == #selector(deleteMe:))
return YES;
return NO;
}
-(BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
Add the methods to a custom UICollectionViewCell. For instance:
-(void)editMe:(UIMenuController *)menuController{
}

How to force an event? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am having a problem with some control i downloaded, i want to change the background when the button is pressed, but it seems that when the button is pressed the app will not listen to any event until the current event is finished here is my code
-(void) menuItem:(RRCircularItem *)item didChangeActive:(BOOL)active {
[menu progress];
[menu setBackgroundColor1:[UIColor colorWithPatternImage:[UIImage imageNamed:#"menuabiertoloadingretina.png"]]];
[menu hideWithAnimationBlock:^{
self.view.backgroundColor = [UIColor whiteColor];
}];
[menu release], menu = nil;
self.viewCarga.hidden = NO;
[menu setBackgroundColor1:[UIColor colorWithPatternImage:[UIImage imageNamed:#"menuabiertoloadingretina.png"]]];
NSLog(#"Item %# did change state to %d", item.text, active);
if ([item.text isEqualToString:#"EDITORIALES"]){
ViewController *viewControler = [[ViewController alloc] initWithNibName:#"EditorialesViewController" bundle:nil];
[self presentViewController:viewControler animated:YES completion:nil];
[menu setBackgroundColor1:[UIColor colorWithPatternImage:[UIImage imageNamed:#"menuabiertoloadingretina.png"]]];
}else if ([item.text isEqualToString:#"GOLES"]){
GolViewController *viewControler = [[GolViewController alloc] initWithNibName:#"GolViewController" bundle:nil];
[self presentViewController:viewControler animated:YES completion:nil];
}else if ([item.text isEqualToString:#"TABLA"]){
WebViewController *viewControler = [[WebViewController alloc] initWithNibName:#"WebViewController" bundle:nil];
[self presentViewController:viewControler animated:YES completion:nil];
}else if ([item.text isEqualToString:#"AUNLI"]){
AUNLIViewController *viewControler = [[AUNLIViewController alloc] initWithNibName:#"AUNLIViewController" bundle:nil];
[self presentViewController:viewControler animated:YES completion:nil];
}else if ([item.text isEqualToString:#"HORARIOS"]){
HorariosViewController *viewControler = [[HorariosViewController alloc] initWithNibName:#"HorariosViewController" bundle:nil];
[self presentViewController:viewControler animated:YES completion:nil];
}
if (active && ![menu isLabelActive]) {
[menu setLabelActive:YES];
[menu setSliderValue:1];
} else if (!active && [menu isLabelActive]) {
BOOL hasActive = NO;
for (int i = 0; i < 6; i++) hasActive |= [menu isItemActive:i];
if (!hasActive) {
[menu setLabelActive:NO];
[menu setSliderValue:0 animated:NO];
}
}
}
i want to use this event [menu progress]; before everything, but it is not working.
if i understand Well, you press some button and you stay lock.Its because you are doing everything in main thread. Thats why you need to use threads, this way you will do multi sync/async processes preventing locks in your app. You can use NSThread, dispatch or NSOperationQueue...I like to use
GCD(Grand Central Dispatch)
Sample:
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Thread
dispatch_async(dispatch_get_main_queue(), ^(void){
//User Interface Updates
});
});

when UISegmentcontrol item changing, why it will hide customBadge in IOS 5?

I have added custom Badge on UISegmentControl. In Xcode 4.0.2 SDK 4.3 its working fine. But in Xcode 4.2 SDK 5.0 custom badge is not shown when another item is selected. I dont know why this happens? I'm using following code for IOS 4.3 Xcode 4.0.2:
- (void)viewDidLoad {
[super viewDidLoad];
super.tableView.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"wallpaper.png"]];
NSLog(#"Root View Loaded");
segmentedControl = [[UISegmentedControl alloc] initWithItems:
[NSArray arrayWithObjects:
#"Home",#"Surveys",#"Results",#"Create",#"Settings",
nil]];
[segmentedControl addTarget:self action:#selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
segmentedControl.frame = CGRectMake(0, 0, 310, 40);
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.tintColor = [UIColor darkGrayColor];
segmentedControl.momentary = NO;
segmentedControl.highlighted = YES;
segmentedControl.selectedSegmentIndex = 0;
UIBarButtonItem *segmentBarItem = [[UIBarButtonItem alloc] initWithCustomView:segmentedControl];
NSArray *segmentBarArray = [NSArray arrayWithObjects:
segmentBarItem,nil];
[[self appDelegate] setSegmentedControl:segmentedControl];
[[self appDelegate] setSegmentBarArray:segmentBarArray];
[self setToolbarItems:[[self appDelegate] segmentBarArray] animated:NO];
[[self navigationController] setToolbarHidden:NO animated:YES];
[self.navigationItem setHidesBackButton:YES animated:YES];
self.navigationController.toolbar.tintColor = [UIColor blackColor];
int surveycount = [[self appDelegate] getUnreadSurveyCount];
surveyCountBadge = [CustomBadge customBadgeWithString:[NSString stringWithFormat:#"%d",surveycount]];
[surveyCountBadge setFrame:CGRectMake(105, -10, surveyCountBadge.frame.size.width, surveyCountBadge.frame.size.height)];
[segmentedControl addSubview:surveyCountBadge];
if (surveycount == 0) {
[surveyCountBadge setHidden:YES];
}else{
[surveyCountBadge setHidden:NO];
}
}
-(void)segmentAction:(id) sender{
UISegmentedControl *segmentedControl = (UISegmentedControl *)sender;
NSLog(#"selected index is %d",segmentedControl.selectedSegmentIndex);
if (segmentedControl.selectedSegmentIndex == 0) {
[self.navigationController popToRootViewControllerAnimated:YES];
} else if(segmentedControl.selectedSegmentIndex ==1){
surveyForMeViewController = [[SurveyForMeView alloc] initWithNibName:#"SurveyForMeView" bundle:nil];
[self.navigationController pushViewController:surveyForMeViewController animated:YES];
} else if(segmentedControl.selectedSegmentIndex ==2){
resultViewController = [[ResultView alloc] initWithNibName:#"ResultView" bundle:nil];
[self.navigationController pushViewController:resultViewController animated:YES];
} else if (segmentedControl.selectedSegmentIndex ==3) {
newSurveyViewController = [[NewSurveyView alloc] initWithNibName:#"NewSurveyView" bundle:nil];
[self.navigationController pushViewController:newSurveyViewController animated:YES];
} else if (segmentedControl.selectedSegmentIndex ==4) {
settingsViewControlle = [[SettingsView alloc] initWithNibName:#"SettingsView" bundle:nil];
[self.navigationController pushViewController:settingsViewControlle animated:YES];
}
}
Any thing else should I mention in this?
You are adding a subview to a segmentedControl. As you don't know how the system redraws the control when another item is selected, you cannot say if your view will be removed or not. Let the control, button or segmentedControl do its work and if you want to add a badge, add it as a subview of its parent.
[surveyCountBadge setFrame:CGRectMake(105.0f+segmentedControl.frame.origin.x,
-10.0f+sementedControl.frame.origin.y, surveyCountBadge.frame.size.width,
surveyCountBadge.frame.size.height)];
[[segmentedControl superView] addSubview: surveyCountBadge];

Trouble Displaying UIMenuController When Cell Tapped In UITableView

I'm trying to display a custom UIMenuController when a User long presses on a cell in a grouped UITableView. However, I can't seem to get the UIMenuController to display after successfully detecting the long press. Any help is greatly appreciated.
MyViewController.h
#interface MyViewController : UIViewController <UITableViewDelegate,UITableViewDataSource>
UITableView *table;
#property (nonatomic, retain) IBOutlet UITableView *table;
#end
In the cellForRowAtIndexPath I attach my Long Press Gesture Recognizer
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SectionsTableIdentifier] autorelease];
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPress:)];
[cell addGestureRecognizer:longPress];
[longPress release];
Here is my handleLongPress action method
-(void)handleLongPress:(UIGestureRecognizer *)longPress {
if (longPress.state == UIGestureRecognizerStateBegan) {
CGPoint pressLocation = [longPress locationInView:self.table];
NSIndexPath *pressedIndexPath = [self.table indexPathForRowAtPoint:pressLocation];
UIMenuItem *first = [[UIMenuItem alloc] initWithTitle:#"Save" action:#selector(saveRecent)];
UIMenuItem *second = [[UIMenuItem alloc] initWithTitle:#"Edit" action:#selector(editQuery)];
UIMenuController *menuController = [UIMenuController sharedMenuController];
menuController.menuItems = [NSArray arrayWithObjects:first,second,nil];
[menuController setTargetRect:longPress.view.frame inView:longPress.view.superview];
[menuController setMenuVisible:YES animated:YES];
[pressedIndexPath release];
}
}
The Action methods for the Edit and Save just display a UIAlertView. I also implemented the below method to ensure that when the UIMenuController is displayed only Save and Edit options will be present
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender {
BOOL canPerform = NO;
if (action == #selector(saveRecent)) {
canPerform = YES;
}
if (action == #selector(editQuery)) {
canPerform = YES;
}
return canPerform;
}
I'm also claiming MyViewController to be first responder
-(BOOL)canBecomeFirstResponder {
return YES;
}
I believe you need to have a view claiming firstResponder status in order to present the UIMenuController. I don't see that happening in your code.
I wrote up directions for using the UIMenuController as an answer to this question:
Customize UIMenuController

UIMenuController Custom Items

I have created a UIMenuController and have set it a custom menu item like so:
UIMenuController *menuController = [UIMenuController sharedMenuController];
UIMenuItem *item1 = [[UIMenuItem alloc] initWithTitle:#"Do This" action:#selector(item1)];
[menuController setMenuItems:[NSArray arrayWithObject:item1]];
But I wanted that object to be the only one to appear so I added this code:
- (BOOL)canPerformAction: (SEL)action withSender: (id)sender {
BOOL answer = NO;
if (action == #selector(item1))
answer = YES;
return answer;
}
The problem is it still shows other## Heading ## items, such as "Select", "Select All" and "Paste".
This may have something to do with this being displayed in a UITextView.
But how do I stop if from displaying all other items?
I think this is one of the few cases where you want to subclass UITextView. I just tried this with the following code, and the only menu item that is shown is my Do Something item.
From my TestViewController.m
#implementation TestViewController
- (void) doSomething: (id) sender
{
NSLog(#"Doing something");
}
- (void) viewDidLoad
{
UIMenuController *menuController = [UIMenuController sharedMenuController];
UIMenuItem *item = [[[UIMenuItem alloc] initWithTitle: #"Do Something"
action: #selector(doSomething:)] autorelease];
[menuController setMenuItems: [NSArray arrayWithObject: item]];
}
#end
Code for my MyTextView.h:
// MyTextView.h
#import <UIKit/UIKit.h>
#interface MyTextView :UITextView {
}
#end
Code for MyTextView.m:
// MyTextView.m
#import "MyTextView.h"
#implementation MyTextView
- (BOOL) canPerformAction:(SEL)action withSender:(id)sender
{
return NO;
}
#end