I'd like to show a popover with it's arrow to a button that is part of my view (e.g. button is on my main view). I do this in Interface Builder storyboard editor (ctrl drag from button to popup contents view). Popup shows but not attached to the button. What I found for the buttons on the toolbar popover shows attached to the button as expected. Anchor property of the segue is set to this button. Xcode Version 7.0.1 (7A1001).
Edit: images of what I do:
1) Storyboard. First I ctrl drag from toolbar button to first controller, then ctrl drag to second controller from second button.
2) Correctly attached popover
3) Popover not attaches to in-view button.
You are right. Following method shows that the sending view is nil and by default contentview of window is used for popover.
So to fix just check if the positioningView is nil. if yes, set it to be button (create outlet for it).
Add following method to your viewController
- (void)presentViewController:(NSViewController *)viewController asPopoverRelativeToRect:(NSRect)positioningRect ofView:(NSView *)positioningView preferredEdge:(NSRectEdge)preferredEdge behavior:(NSPopoverBehavior)behavior
{
//do custom implementation (workaround)
[super presentViewController:viewController asPopoverRelativeToRect:positioningRect ofView:positioningView preferredEdge:preferredEdge behavior:behavior];
}
Related
I have a UIViewController that adds other UIViewControllers as children so that I can use their views to create a menu hierarchy. The following images represent my current interface.
The interface before displaying the menu:
The interface after displaying the menu:
The following explains my hierarchy:
In AppDelegate I create an instance of MainContainerViewController and set it as the window's rootViewController. The view controller acts as a container allowing me to add Chile view controllers.
In MainContainerViewController I create an instance of CenterViewController and add it as the rootViewController of an UINavigationController. I add the navigation controller as a child view controller, adding the navigation controller's view as a subview of MainContainerViewController. I also create an instance of LeftMenuViewController, adding it as a child view controller and inserting its view below the navigation controller's view. This allows me to tap the UIBarButtonItem of CenterViewController and show the menu by sliding the navigation controller's view to the right.
I have added an UIScreenEdgePanGestureRecognizer to the navigation controller's view which allows me to show the menu by sliding CenterViewController's view off to the right.
I have added an UITapGestureRecognizer to the navigation controller's view which allows me to close the menu by tapping the navigation controller's view.
I want to be able to use an UIPanGestureRecognizer to allow the user to interactively close the menu similar to how Slack allows, if you're familiar with their mobile UI.
I added the pan gesture recognizer to the navigation controller's view, just as I did with the two aforementioned gesture recognizers. However, I can't get the UIScreenEdgePanGestureRecognizer and UIPanGestureRecognizer to play well together. I have tried implementing combinations of UIGestureRecognizerDelegate methods without success. I feel a little lost with gesture recognizers, and I don't know where to start with trying to get these gesture recognizers to play well.
I have followed Apple's example, adapted to my requirements. If the menu is not displayed, then the UIPanGestureRecognizer should allow the UIScreenEdgePanGestureRecognizer to open the menu.
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if leftMenuState == .hidden {
if gestureRecognizer == panGestureRecognizer && otherGestureRecognizer.view!.isDescendant(of: gestureRecognizer.view!) {
return true
}
}
return false
}
What I expect:
Ability to display menu by using UIScreenEdgePanGestureRecognizer
Ability to tap CenterViewController and have menu close
Ability to pan CenterViewController and close menu
What happens:
Menu is not opened by panning with UIScreenEdgePanGestureRecognizer because UIPanGestureRecognizer receives events
Menu is opened by UIBarButtonItem
Menu is closed by UIBarButtonItem or UITapGestureRecognizer
What do I need to do to enable the intended functionality?
I have created two views in my main storyboard ->
Now I added a button on the first one which should link to the other one (so when I press it it should lead to the other view). I have id't the one I want to link to with SceneViewController.
I copied the following code (and defined the method in the header) ->
- (IBAction)button:(id)sender {
SceneViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"SceneViewController"];
[self.navigationController pushViewController:controller animated:YES];
}
But nothing happens when I press the button. Anybody a clue on what I'm doing wrong?
Thanks, cheers!
It's not enough to just copy the IBAction code. You have to link the button in the storyboard to the IBAction method you created in your header file.
Open your storyboard, click on the Assistant Editor icon at top right of screen (little icon of a waistcoat and bow tie). Make sure the right pane has your header file selected, if not you can chane to it in the drop down at the top.
Then zoom in on your button, right click on it and drag to the IBAction line in your header file. This should create the connection for you.
I can't get the standard back button of iOS into a navigationBar because I can't find it in the Object Library, so can I do it with code or something else?
I just want the normal, standard, blue back button - you know which I mean.
To "automatically" have a back button you need first have a UINavigationController. Then you need to take a different UIViewController and add it as the root view controller in UINavigationController's init method:
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:someOtherViewController];
Be sure to also set a title for someOtherViewController, usually in it's viewDidLoad or initializer. I'll tell you why this is important in a second:
self.title = #"Some other VC";
Then take a second UIViewController and push it onto your navigation controller:
[navigationController pushViewController:anotherViewController animated:YES];
You now have two UIViewControllers on your navigation stack: someOtherViewController and anotherViewController.
Your view will now have a back button with "Some other VC" in it. This is the title of the view controller that was just moved out of view:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UINavigationController_Class/Reference/Reference.html
http://simplecode.me/2011/09/04/an-introduction-to-uinavigationcontroller/
I would also suggest reading up on how UINavigationControllers work and searching this site a bit more for customizing the back button. There are plenty of threads about it.
You can't add the back button yourself. The back button is part of the Navigation controller. If you embed a Navigation controller into your view(s), the back button will appear and be populated by the name of the previous view.
If you're using storyboards select your view controller, then in top menu choose "editor" -> "embed in" -> "navigation controller".
Edit: Here is an exmaple.
I'm running Xcode 7.2. This was driving me crazy, but I figured it out. Here are all the pieces you need to make the Back button appear (make a test project to prove it):
1) You have to have a Navigation Controller and it has to be set to be the initial view controller. So add the Navigation Controller, you will import two tables. Click on the Navigation Controller and on the properties list, check the box that reads "Is Initial View Controller". You will now see and arrow pointing to this view.
2) In our case we want a ViewController and not the included / connected TableViewController, so delete the TableViewController (RootController) and add a new ViewController.
3) Connect the Navigation Controller to the new ViewController by clicking on the top bar of the Navigation controller and orange circle with the arrow pointing left. Hold the Control button on your keyboard down and click and drag from the orange circle to the ViewController and let go. When given the list of options on how to connect the two views, select 'root view controller'.
Done! Now you the functioning navigation bar and you automatically get the back arrow on all segues added. Test this. Add another ViewController and connect to it with a button on the existing ViewController. Use the Control-click-drag approach from the button to the newest ViewController. Select the 'show' option for the new segue you created.
Run it. You'll see the back option has automatically appeared when you click the button and moved to the newest ViewController.
This is all provided by the Navigation Controller, but only when you make another controller the RootController. Happy navigating!
I have made tabbed bar application.Then I put a navigation bar + bar button on one tab view.Then I put a separate view controller on my storyboard.Now i want to open that separate view on click of that bar button.I have tried this by connecting button to view controller with push option.But it does not works.please help?
Then I put a navigation bar + bar button on one tab view.
Seems that you have tried to add UINavigationBar by yourself and as a result (I guess) you have no UINavigationController on tab view. In this case your push segue will not work.
Just place UINavigationController on first tab. Place your bar button on navigationBar that owned by navigationController. The image will help you understand what I've said.
I created a simple cocoa project, and added an NSButton in the window.
Then I added an NSScrollView to the window and hided the NSButton.
However, when I click the scroll view , it is strange that the NSButton action responds!
I guess there is something with the touch event chains, but I failed to find it.
For example, I try to use:
- [NSView becomeFirstResponder];
- [NSView setAcceptsTouchEvents:];
SO what I want is the only the front-most view to become the first responder, and the touch event will not be sent to its superview or so.
Thanks.
This is the view hierarchy:
the scroll view and button are both added to the window view, and the scrollview's frame includes the button's frame. In other words, the button is hidden by the scroll view but still receives click events.
You need to add mouseDown: event in NSScrollView or NSCrollView's View. like this:
-(void)mouseDown:(NSEvent *)theEvent {
NSLog(#"MouseDown in NSView");
}