I have a ViewController with a full screen UIImageView. I've hidden statusBar and NavigationBar, so there is no way to go back but tapping somewhere.
So i was thinking to go back just using this touchesBegan
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self dismissModalViewControllerAnimated:YES];
}
I also tried to use this way
-(void)viewDidLoad
{
[super viewDidLoad];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[self.navigationController setNavigationBarHidden:YES];
UITapGestureRecognizer *tapRecognizer;
tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissModalViewControllerAnimated:)];
[imageFrame addGestureRecognizer:tapRecognizer];
imageFrame.image = [UIImage imageWithContentsOfFile:image];
[tapRecognizer release];
}
I got stuck there, with this full screen image and i can't go back.
How can I dismiss the viewcontroller?
If you are using a navigation bar I'm assuming that you did a pushViewController to start this view controller? In which case you would want
[self.navigationController popViewControllerAnimated:YES];
to dismiss the controller.
Of course your solution assumes that the image view is in fact a modal view controller presented with presentModalViewController:animated: somewhere.
My suggestion would be to have a UIButton placed on top of your image view and sized the same. Hook up its Touch Up Inside to your go-back method and then set its alpha to 0 or Hide it through IB or properties. The button won't be displayed but it'll still receive touch events.
You should call dismissModalViewControllerAnimated: on the parent view controller, and not on the one you wanna hide.
Also make sure to set the UIImageView's userInteractionEnabled property to yes, because unlike regular UIView's it doesn't answer touch events by default.
Related
I want to swipe in my app to push or pop ViewControllers , I know I can add a swipe gesture to that.
But When I swipe the screen ,I want the current ViewController followed with my swipe gesture ,and next ViewController pushes in just with the swipe. How can I do this,Thank you!
Not possible with UINavigationController; you'll have to build your own navigation controller (should be pretty easy) that incorporates a UIPanGestureRecognizer.
EDIT for iOS 7: You'll probably want to use a UIScreenEdgePanGestureRecognizer.
Gesture recognizers have action methods just like buttons. Just put this in the action method:
NextViewController *next = [[NextViewController alloc] init ....];
[self.navigationController pushViewController:next animated:YES];
Read about gesture recognizers. You can create them and add it on objects.
For example
UILongPressGestureRecognizer *longTap = [[UILongPressGestureRecognizer alloc]
initWithTarget:self
action:#selector(longPress:)];
longTap.minimumPressDuration = 1.0;
[cell addGestureRecognizer:longTap];
Here I have created LongPress recognizer and added it on my cell. If I will longpress(1.0 sec) on my cell, it will call selector(longPress:). In long press I can make any code.
-(void)longPress : (UILongPressGestureRecognizer *)rec {
if (rec.state == UIGestureRecognizerStateBegan) {
NSLog (#"I've longPressed");
}
}
You can use different recognizers by the same way.
About push and pop. They are methods of Navigation controller.
Push - goes forward, on controller which you shows him;
NextController *goNext = [[NextViewController alloc] init];
[self.navigationController pushViewController:goNext animated:YES];
it will go to the NextController.
Pop - backs to the previous controller.
Here you don't need to show the previous controller. Just say to navController back
[self.navigationController popViewControllerAnimated:YES];
I have a View With Navigation Bar
Actually I have taken a Image View and Put it on a navigation bar....
As I want Button Not at right or Left but at somewhere on the navigation bar
By this method I can recognize touch on view but can not recognize touch on Navigation Bar ?
Can I change anything...
In this method...
Why?
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *) event {
CGPoint p;
p.x=0;
p.y=0;
p = [[touches anyObject] locationInView:self.nvbrCalculateBar];
NSLog(#" %f",p.x);
if(p.x==0 && q.x==0)
{
}
else
{
//Load View
}
}
You can add a UITapGestureRecognizer to your UIImageView and that should do the trick
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapEvent:)];
[yourImageView addGestureRecognizer:tap];
[tap release];
- (void)tapEvent:(UITapGestureRecognizer *)gesture {
//Do whatever you need when user taps the imageView
}
Also set the userInteractionEnabled of the imageView to YES to be able to receive the gesture recognizer events.
Hope this helps.
The UINavigationBar itself is not set to return touches, since I believe its not part of the actual UIView (for which the touchesBegan) method applies. Instead, you can push various items onto the nav bar (e.g. buttons) which you can define interactions for.
See its reference here.
USer Interaction Must be enabled of UINavigation Bar Property, And then Apply touch method..
Can you try:
[imageView setUserInteractionEnabled:NO];
This should prevent your imageview to cancel the touches.
I am using XCode to develop a Cocoa touch application for the iOS platform but have had trouble finding out how to get a swipe gesture implemented that would allow the user to swipe their finger left or right to change to a new ViewController (nib/xib file). I have done a swapView IBAction using a button and modal transitioning and I have read about Apple's TouchGestureRecognizer but I don't know how to implement a swipe action that would allow a view change.
I do NOT want to use a scroll view, as I have several dozen view controllers, that I want the user to be able to swipe through.
Here is an example:
First View Controller.xib:
SwipeRight- Go to second View Controller.xib
Second View Controller.xib:
SwipeLeft- Go to first View Controller.xib
SwipeRight- Go to third View Controller.xib
etc, etc
I have not used UISwipe/Touch Gestures before but I have used an IBAction method to switch views using a button with Modal Transitioning (see below):
-(IBAction)swapViews; {
SecondViewController *second2 =[[SecondViewController alloc initWithNibName:#"SecondViewController" bundle:nil];
second2.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:second2 animated:YES];
[second2 release];
}
Is using a swipe to do a similar method formatted differently? If so, how do I sort this out and format it.
Thank You
Edit - Answer as Per Comment on Question
Place this in your viewDidLoad
UISwipeGestureRecognizer *swipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeLeftDetected:)];
swipeRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:swipeRecognizer];
[swipeRecognizer release];
Then add a selector as by pasting the following code into your main...
- (IBAction)swipeLeftDetected:(UIGestureRecognizer *)sender {
NC2ViewController *second2 =[[NC2ViewController alloc] initWithNibName:#"NC2ViewController" bundle:nil];
second2.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:second2 animated:YES];
[second2 release];
}
Then just make sure you import the otherViewController you are swapping to using
#import "SecondViewController"
at the top of your main file. Hope this helps.
End Edit
This sounds like a perfect time to use UIGestureRecognizer or, more specifically, UISwipeGestureRecognizer.
For more info on how to use them, read up in the Gesture Recognizers section of the Event Handling Guide.
Lets assume you want to swipe left to bring up another view from the right.
In the storyboard, drag and drop a swipe gesture recognizer. It will make an icon below the view controller; drag this icon and drop onto the ViewController you want to navigate to. This will add a segue, select custom segue. Then create a UIStoryboardSegue class. Add the following code:
- (void)perform {
UIViewController* source = (UIViewController *)self.sourceViewController;
UIViewController* destination = (UIViewController *)self.destinationViewController;
CGRect sourceFrame = source.view.frame;
sourceFrame.origin.x = -sourceFrame.size.width;
CGRect destFrame = destination.view.frame;
destFrame.origin.x = destination.view.frame.size.width;
destination.view.frame = destFrame;
destFrame.origin.x = 0;
[source.view.superview addSubview:destination.view];
[UIView animateWithDuration:0.5
animations:^{
source.view.frame = sourceFrame;
destination.view.frame = destFrame;
}
completion:^(BOOL finished) {
UIWindow *window = source.view.window;
[window setRootViewController:destination];
}];
}
I have a dilema, I want to present to the user a semi-transparent view.
I found out by experimenting that if I simply pushed the transparent view to the top of my NavigationController's stack, that it would not render the transparency level I wanted. So I decided to simply add the view as a subview of the current view at the top of the stack.
This solution works, the view below is still visible, and the View is 'semi-modal'. The problem is, if the parent view inherits from UITableViewController (as mine does), then the view I 'push' onto it, does not cover the navigation bar at the top.
I really don't want to get into a situation where I am forced to enable / disable controls on the navigation bar every time I push this view, so I was wondering, if anyone knew of any solutions that I could use so that the view I push onto the UITableViewController will actually 'push over' the navigation bar?
Funny, I was just doing the same thing yesterday. Unfortunately it seems to be impossible. Once the modal view controller is in place, the previous view becomes hidden.
See this previous question on the topic.
You can still use the view controller and NIB files you have set up - here's my sample code
- (void)showUpgrade {
[self.upgradeVC viewWillAppear:NO];
[self.view addSubview:self.upgradeVC.view];
[self.upgradeVC viewDidAppear:NO];
}
- (void)hideUpgrade {
[self.upgradeVC viewWillDisappear:NO];
[self.upgradeVC.view removeFromSuperview];
[self.upgradeVC viewDidDisappear:NO];
}
- (UpgradeViewController *)upgradeVC {
if (_upgradeVC == nil) {
_upgradeVC = [[UpgradeViewController alloc] initWithNibName:[NSString stringWithFormat:#"UpgradeView_%#", self.deviceType] bundle:nil];
_upgradeVC.delegate = self;
}
return _upgradeVC;
}
You will need to store a reference to the parent view controller in the modal view controller so that you can access the -hide method. I did this through a delegate.
It would also be easy to add some animation to -show and -hide if you want it to animate up from the bottom of the screen - I was just too lazy to do this.
iOS 8 added the UIModalPresentationOverFullScreen presentation style. Set this as the presented view controller’s modalPresentationStyle. For more advanced needs, look into creating a custom presentation controller.
There is now a way to achieve this using iOS7 custom transitions :
MyController * controller = [MyController new];
[controller setTransitioningDelegate:self.transitionController];
controller.modalPresentationStyle = UIModalPresentationCustom;
[self controller animated:YES completion:nil];
To create your custom transition, you need 2 things :
A TransitionDelegate object (implementing
<UIViewControllerTransitionDelegate>)
An "AnimatedTransitioning" object
(implementing <UIViewControllerAnimatedTransitioning>)
You can find more informations on custom transitions in this tutorial : http://www.doubleencore.com/2013/09/ios-7-custom-transitions/
Try this:
ViewController *vc = [[ViewController alloc] init];
[vc setModalPresentationStyle:UIModalPresentationOverCurrentContext];
[self presentViewController:vc animated:YES completion:nil];
Have you tried looping over the Modal View Controller's subviews and setting the background color to clear for every view? This is a DFS recursive function.
- (void)setBackgroundToClearForView:(UIView *)view {
if ([view subviews]) {
for (UIView *subView in [view subviews]) {
[self setBackgroundToClearForView:subView];
}
}
if ([view respondsToSelector:#selector(setBackgroundColor:)]) {
[view performSelector:#selector(setBackgroundColor:)
withObject:[UIColor clearColor]];
}
}
To use it call:
[self setBackgroundToClearForView:self.view];
in viewDidLoad.
This will do the trick.. Try this one.
// for clear color or you can easily adjust the alpha here
YourVC *vc=[[YourVC alloc]initWithNibName:#"YourVC" bundle:nil] ;
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];
So that the view will be full screen unlike UIModalPresentationFormSheet..
In my app I have a tabBarController and in it a navigationController. One of my view controllers is a TableViewController and under the navigationBar i added a uiView as a subview to the view like this:
rectangleInfo = [[UIView alloc] initWithFrame:CGRectMake(0,0,[[UIScreen mainScreen] applicationFrame].size.width,26)]; rectangleInfo.autoresizingMask = (UIViewAutoresizingFlexibleWidth); rectangleInfo.backgroundColor = [UIColor darkGrayColor]; [self.view addSubview: rectangleInfo];
when I click on a cell in the tableView I push an UIViewController like this:
[feedViewController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[[self navigationController] presentModalViewController:feedViewController animated:YES];
After i pop the modal view for a couple of times with it from the tableViewNavigationController disappears the rectangleInfo UIView.
I pop my modalview like this:
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:YES];
[self setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self dismissModalViewControllerAnimated:YES];
any idea why that subview (rectangleInfo) of the tableViewController dissapears after i remove the modal view from the superview?
thank you in advance.
I'm curious as to what you are trying to do with your rectangleInfo view? By the size of it, it looks like you are trying to mimic the status bar. Why? You can just hide the status bar if you want.
Another thing you can try is to create the UIView visually in Interface Builder. Don't actually add it to your main view, but create it as a separate UIView in the XIB with the appropriate size, etc. Then create an outlet for it in Xcode and connect it. Next, add it as a subview in code when your view controller loads. See if that makes a difference. This is especially strange since you say it only disappears after popping it several times. Do you get the same problem if you push and pop the non-modal way, e.g.:
[[self navigationController] pushViewController:feedViewController animated:YES];
[[self navigationController] popViewControllerAnimated:YES];
i solved the problem by implementing correctly the viewDidLoad and viewDidUnload methods for creating and releasing my subviews.