iPad UIPopoverController does not go over inputView in UITextView - cocoa-touch

I am trying to set up a popover to point to a UIButton in a view that is used as a "inputView" to a UITextView. I can get everything to work and the correct data is going into the UIPopoverController. But it is exhibiting a behavior that is not what I expected. So here is what I have. The following method is written in a UIView subclass that is the inputView of the UITextView and is also the view in which the button resides.
- (IBAction)buttonTouchDown:(id)sender {
UIButton *button = (UIButton *)sender;
MyPopoverContentController *controller = [[MyPopoverContentController alloc] initWithNibName:#"MyNib" bundle:nil];
[controller setContentSizeForViewInPopover:CGSize(320.0, 304.0)];
self.popupController = [[UIPopupController all] initWithContentViewController:controller];
[self.popupController presentPopoverFromRect:[button frame] inView:self permittedArrowDirectoions:UIPopoverArrowDirectionDown animated:YES];
}
Now, I would expect the popover to float over the inputView and the pointer would touch the button I've placed into the view. But it does not. In the 'X' origin the popover point is correct. But it appears the UIView when acting as a input view it won't allow the popover to move down over the inputView to the UIButton. Am I overlooking something?
Thanks for any help,
Rob

It's been a while since I visited this question. I turned this in to Apple and it is a bug. They are working on it.

Try:
[self.popupController presentPopoverFromRect:button.bounds inView:button permittedArrowDirectoions:UIPopoverArrowDirectionDown animated:YES];

Related

UIView inside a UIViewController or better way to do it?

I have a problem on how to properly do a certain kind of action.
The image below shows a UIViewController, but the second part of the view is a custom UIView (the one with the profile pic, name and Show View button).
The subclassed UIView is allocated using this code:
profileView = [[GPProfileView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 70)];
profileView.myTripGradientColor = YES;
[self.view addSubview:profileView];
The problem is of course, that the button on the UIView can't show any view, since it's only the UIViewController that can push another ViewController to the window(correct?).
The UIView is used in several places in the app and needs to be added easily and have the same behavior across the application.
This worked great until I added the button, and I'm starting to think I've made this wrong, and there has to be a better way to do it (maybe change the UIView to something else?).
I was thinking I should be able to call:
self.superview
And then somehow get the ViewController so I can push another ViewController into the view hierarchy, but nope.
Any suggestions and a tips on how to do this correctly?
UPDATE:
I have no idea on how to push another UIViewController from the button.
What should I do in this method when pressing the button in the UIView:
- (void) showViewButtonTouched:(UIButton*)sender {
GPProfileSocialFriendsViewController *friendsSettings = [[GPProfileSocialFriendsViewController alloc] init];
}
How do I push GPProfileSocialFriendsViewController?
Your - (void) showViewButtonTouched:(UIButton*)sender method should be in your controller and would probably be better named - (void) showView:(UIButton*)sender or - (void) showProfile:(UIButton*)sender so it clearly denotes what it does (not how you got there).
It's not the view's responsibility to manage transitions from a state to another. If you move your method to your controller, your problem is no more (you can easily access self.navigationController or push directly if you don't have an navigation controller like this:
[self presentViewController:vcThatNeedsToBePushed animated:YES completion:nil];
I think you can create weak reference in GPProfileView on UIViewController. Like this:
#property (weak, nonatomic) UIViewController *rootController;
when you create GPProfileView, assign rootController-property:
profileView = [[GPProfileView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 70)];
profileView.myTripGradientColor = YES;
profileView.rootController = self; // if view created in view controller
[self.view addSubview:profileView];
and in implementation of button selector:
self.rootController push... // or pop
May be this not correct, but you can try
You could let the view controller push the next view controller when the button is pushed. The view controller can add a target/action on the button, so that the action method in the view controller is called on the touch up inside event.

EXC_BAD_ACCESS at removeFromSuperview - using ARC

In one of my ViewControllers (ViewController A), I have the following code:
AlertViewController *aViewController = [[AlertViewController alloc] initWithNibName:#"AlertViewController" bundle:nil];
[self.view addSubview:[aViewController view]];
[self.view bringSubviewToFront:[aViewController view]];
And in AlertViewController, I have a button and when the user clicks on it, I have:
[self.view removeFromSuperview];
Whenever I click the button, the result is EXC_BAD_ACCESS.
I'm unable to figure out the problem. My project is using ARC and ViewController A is part of a navigation controller stack if that info helps.
The problem here is that the UIView doesn't own its UIViewController. In the first block of code you held the UIView around by adding it to a subview, but let the UIViewController go away. The UIView from a UIViewController is special, you can't let this happen.
Make sure the UIViewController that created the UIView lives as long as the view does.

Right gesture not working

In my project, i have two views. One is homeViewController and other is searchViewController. I have done right swipe gesture on homeViewController to show searchViewController. But UISwipeGestureRecognizerDirectionRight doesn't work for me. It gives left animation rather than right.
I have added below code in homeViewController.m to add gesture property and show SearchViewController:
UISwipeGestureRecognizer *swipeRecognizer=[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeDetected:)];
[swipeRecognizer setDirection:UISwipeGestureRecognizerDirectionRight];
[self.view addGestureRecognizer:swipeRecognizer];
[swipeRecognizer release];
-(void)swipeDetected:(UIGestureRecognizer *)sender
{
SearchViewController *searchView=[[SearchViewController alloc] initWithNibName:#"SearchViewController" bundle:nil];
[self.navigationController pushViewController:searchView animated:YES];
[searchView release];
}
Please help me out.
Thanks.
The animation here is coming as part of the navigation controllers pushViewController:animated: method, it has nothing to do with the direction of the gesture recognizer (that only determines which way the user needs to swipe in order for the swipe to be recogized)
if you want to be able to swipe between view controllers in other directions you could look at UIPageViewController

Trying to dismiss subview and UIView

I'm still very new to iOS developing. In fact, if there is a super noob, I would be one :p. Currently I am working on creating an IBAction button that accesses a subview. I have 2 ViewControllers, AddClientVC and NewClientVC, both with .nib files. So basically, inside my AddClientVC I implement an IBAction button with the following code:
- (IBAction)buttonPressed:(id)sender
{
UIView *transparentBG = [[UIView alloc] initWithFrame:CGRectMake(-5, -5, 1500, 2500)];
transparentBG.backgroundColor = [UIColor blackColor];
transparentBG.opaque = NO;
transparentBG.alpha = 0.5;
[self.view addSubview:transparentBG];
transparentBG.center = transparentBG.center;
vc = [[NewClientVC alloc] initWithNibName:#"NewClientVC" bundle:nil];
[self.view addSubview:vc.view];
vc.view.center = self.view.center;
}
As you can see I implemented a UIView as a transparent background. Basically AddClientVC --> Transparent Background --> NewClientVC. Now I have created another IBAction button but this time inside NewClientVC as a function to dismiss the accessed subview which looks like this:
- (IBAction)saveDismiss:(id)sender
{
[self.view removeFromSuperview];
}
The problem I'm having right now is when I click the saveDismiss button it only removes the subview that I called previously on AddClientVC but it didn't remove the transparent background I have created as a UIView. So the problem is how do I implement an action which simultaneously removes my subview and the UIView transparent background I created.
I need all the help I can get :)
I'm not too sure I fully understand what you want to happen, but maybe you could try something like this?
- (IBAction)saveDismiss:(id)sender
{
[vc removeFromSuperView];
[self.view removeFromSuperview];
}
I recommend not to manage your screens by adding subviews manually but instead use
- (void)presentModalViewController: (UIViewController *)modalViewController
animated: (BOOL)animated
method on your root viewController.
Or better instantiate a UINavigationController and use push and pop methods to drill down/up your views.
See apple reference here
Do not worry about code execution speed and stay confident in apple's SDK. UIKit is optimized for best user experience. Trying to boost your code by doing inappropriate SDK use is, in my opinion, a risky strategy. ;) – Vincent Zgueb
Sorry Vincent but I don't agree with you. I reached here because I want to implement an gesture that adds a sub-view for my view, which will be the navigation of my app.
[self.view addSubview:ctrl.view];
is faster presenting the view than
[self.navigationController presentModalViewController:ctrl animated:NO]
and by the way, the solution to the topic in my case was:
[self.view sendSubviewToBack:ctrl.view];

presentModalViewController ontop of subview?

I am trying to recreate the iPhone's tabView, but with my own style, buttons, etc. I didn't want to have to totally redo my app, so I simply added a view to the bottom like this [window addSubview:theToolbar]; theToolbar.frame = CGRectMake(0, 425, 320, 44); in my appDelegate.
However, when trying to do this from a view inside a navigationController theToolbar is over it. Is there anyway to somehow present it to the front?
Here's my code to present the view:
AppSettingsController *appSettings = [[AppSettingsController alloc] initWithNibName:nil bundle:nil];
appSettings.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:appSettings animated:YES];
[appSettings release];
Thanks.
it's impossible show partial views of the viewcontroller. if your want to use the same toolbar, you should retain the toolbar to your appdelegate, and add the toolbar to each viewcontroller when it is in view.
or you should just use uiview's as viewcontrollers