Animate a view on key window while dragging another view with UILongPressGestureRecognizer - ios

I have added UILongPressGestureRecognizer to a view, and after long press event, the user can drag the view.
I have added a view on the key window (need the custom view over the navigation and tab bar controllers, that is why need to add it on key window) using below code:
// add the custom view on the key window.
UIWindow *currentWindow = [UIApplication sharedApplication].keyWindow;
[currentWindow addSubview:customView];
Now, when I am dragging the first view beyond the (screenSize/2) point, I want the customView to animate from the right side of the view. I tried the following code to present the view:
// animate the customView view.
[UIView animateWithDuration:0.50f animations:^{
customView.frame = CGRectMake(SCREEN_WIDTH - customViewWidth, 0, customViewWidth, SCREEN_HEIGHT);
} completion:nil];
But the view does not appear neither it animates. I even tried to use the dispatch_async(dispatch_get_main_queue(),{}); but still no success.
Any help will be appreciated.

You should use UIAttachmentBehavior.
It specifies a dynamic connection between two dynamic items, or between a dynamic item and an anchor point. When a dynamic item moves, either by tracking a gesture or via other input, any attached dynamic item also moves—if possible given its other dynamic parameters and boundaries. You can configure an attachment behavior using its length, damping, and frequency properties.

Related

Synchronise animation with top of a keyboard with accessory view

I have a UITextField which has an accessory view. I also have another view which resides at the bottom of the screen. I want this view to animate up as the keyboard shows, which I have done plenty of times by utilizing the UIKeyboardWillShowNotification. However, this time it is a little special since I want the bottom view to follow the top of the keyboard and not the top of the accessory view.
Obviously I have tried this solution:
[UIView animateWithDuration:keyboardAnimationDuration delay:0 options:keyboardAnimationCurve animations:^{
viewBottomConstraint.constant = keyboardHeight - accessoryViewHeight;
[self.overviewViewController.view layoutIfNeeded];
} completion:nil];
(keyboardAnimationDuration, keyboardAnimationCurve and keyboardHeight all come from the userInfo dictionary of the keyboard notification)
This solution gives me the correct end position of the bottom view, but the animation is slightly off since the keyboard (including the accessory view) has to traverse a longer distance in the same duration (to the top of the accessory view instead of to the top of the keyboard).
I have considered calculating a relative animation duration for my bottom view like this:
keyboardToAccessoryRatio = (keyboardHeight - accessoryViewHeight) / keyboardHeight
relativeDuration = keyboardAnimationDuration * keyboardToAccessoryRatio
And then have the animation start with a delay of keyboardAnimationDuration - relativeDuration. However, this would only work nicely if the keyboard was using the UIViewAnimationOptionCurveLinear curve, but it is, in fact, using UIViewAnimationCurveEaseInOut.
So any other suggestions?
PS. I cannot simply add my button view to the accessory view as they are actually in separate view controllers. The animation is done as a part of a custom transition within a UIViewControllerAnimatedTransitioning class.
In the end I gave up and added the accessory view as a regular view which I made follow the keyboard.

Create a submenu iOS

I want to create a submenu that will appear right next to the first menu and that will contain more options. The first menu is hidden and only appears when a button its clicked on the navigation bar, i used the SWRevealViewController from github for the first menu, but i can't make the second one appear . Can somone help ?
Thanks for any help in advance
Basically you add another SWRevealController as front view controller of the root SWRevealController.
UIViewController *secondRearVC = // your second level menu controller
UIViewController *secondVC = // your second level front view controller
SWRevealViewController *childRevealController =
[[SWRevealViewController alloc] initWithRearViewController:secondRearVC frontViewController:secondVC];
[rootRevealController setFrontViewController:childRevealController animated:YES];
You can find example of what I've suggested here.
Other option is using other side menu controller, JASidePanels, if I'm not wrong it does what you want. Anyway you'll end up using some UIViewController containers recursively, so it's just a matter of choice.
For this effect i have created a separate view say reveal view with UITableView init, at first i am giving zero width and full height for that view. If the navigation button is pressed , i am moving the main view to right like about 100px and change the width of the reveal view to 100px, place that code in animation block.
[UIView animateWithDuration:0.5 animations:^{
//Move frame or transform view
revealView.frame = CGRectMake(0,0,1,screenHeight);
mainView.frame = CGRectMake(0, 0, 320, screenHeight);
}];

how to show an overlapping view iOS

I have a view with some UI components and a button on it, upon touch of a button I want to show a half view with some textfields on it overlapping the initial view, the initial view should be visible partly , the overlapping view will cover only half screen from bottom. Is this possible ?
I don't have any code as I am unable to figure out what it needs to be done, as we show any view it covers the entire screen.
Thanks
there are several ways you can do this, here are two:
1) add a popover controller that gets displayed on your button press:
here's some apple documentation on popovers: https://developer.apple.com/Library/ios/documentation/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/Popovers.html
2) add the new view as a subview to your UIViewController
PROGRAMICALLY:
in the viewDidLoad function you can do the following to initialize the halfScreenView
GLfloat topOffset = self.view.frame.size.height/2;
UIView halfScreenView = [[UIView alloc] initWithFrame: CGRectMake(0, topOffset , [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - topOffset)
[self.view addSubview:halfScreenView];
-more logic might be needed if you support Landscape orientation, you can always re-assign the location of the view with halfScreenView.frame.origin and halfScreenView.frame.size
-initially you can have this view be hidden
halfScreenView.hidden = YES;
-when you click the button it will show the overlaying view:
halfScreenView.hidden = NO;
USING STORYBOARD:
you can also set up your overlaying view in the storyboard if you have one
-drag a UIView into your UIViewController and set it up where you want it to be located
-initialize the view to be hidden by checking the hidden box in the attribute inspector
-add the view as a property to your view
-manage when to show this view with self.halfScreenView.hidden
-this technique allows you to customize what is inside the new view within the storyboard which is nice
FOR BOTH:
-be careful with layers, you don't want your view to show up behind the one you already present. In the storyboard the last thing inserted goes on top. With in the code you can always access/change the views z position with halfScreenView.layer.zPosition (higher z values are on top)
First create a new class subclassing UIViewController called SecondView (or whatever you want), then design the UI the way you want (in its .xib file)
Then go to your main view controller's file and make an IBAction for that button.
In that method, write:
SecondView* second = [[SecondView alloc] initWithFrame:CGRectMake(0, [[UIScreen mainScreen] bounds].size.height/2, height, width);
[self.view addSubview:second.view];
This will add it to the bottom half of the screen. Put your own parameters for its height and width. When you want to dismiss the view, you can do this inside your SecondView class
[self.view removeFromSuperview];
You can deal with the textFields from within the SecondView class and have them communicate with your other view by doing the following in SecondView.h
#property IBOutlet UITextField* textField;
Hope this helps!
Yes, assuming you are using Interface Builder, go ahead and build the overlapping view and hook up all of the IBOutlets and IBActions. Say this view is called myView. Set myView.hidden = YES and myView.enabled = NO. This hides and disables myView so that it isn't even there from the user's perspective. In the appropriate button's IBAction, change the hidden and enabled properties to YES. That will make the view visible and active again.

Xcode 5 - Swipe switch view with constant background

I understand how to implement UISwipeGestureRecognizer, but I do not understand how to use multiple views properly in collaboration with it.
My ultimate goal is to provide a sleek interface where buttons or swiping may be used to change views. I am hoping for a constant background rather than a background image show it is transferring to the exact same image again. I am using storyboarding currently where each view has its own controller, and I would like (if possible) to keep it as close to this format for visual clarity of what is going on.
I have read that subviews may be my best hope for this sort of scenario (keeping them to the right until a swipe is called), but that would break up the current storyboarding structure I am using, and most certainly ruin any visual clarity.
Does anyone have any suggestions?
I did same programmatically, but you can achieve same using storyboard
1. You need base view which will keep same background
2. Add 3 Views (or 2 depending on ur requirement) Left, Middle, Right with transparent backgrounds as follows in viewDidLoad of base view controller
[self addChildViewController:myChildViewController];
[myChildViewController view].frame = CGMakeRect(x,y,width,height);//Left one will have x = -320, y=0 ,Middle x= 0, y= 0, Right x = 32O etc.
/* Add new view to source view */
[self.view addSubview:[myChildViewController view]];
/* Inform 'didMoveToParentViewController' to newly added view controller */
[myChildViewController didMoveToParentViewController:self];
3. In handle Swipe method change frames of view with animation which will make it look like swiping page
e.g
//swipe left, get right view in middle
[UIView animateWithDuration:0.2 animations:^{
CGRect frame = rightViewController.view.frame;
frame.origin.x = 0;
frame.origin.y = 0;
rightViewController.view.frame = frame;
CGRect middleViewFrame = middleViewController.view.frame;
middleViewFrame.origin.x = -320;
middleViewController.view.frame = middleViewFrame;
}];
You could use a navigation to do this. If you don't want the navigation bar, you can hide it. You can connect the left swipe gesture recognizer to a segue to the next controller, and connect the right swipe gesture recognizer to an unwind segue (or call popViewControllerAnimated: from its action method). If you want a constant background, then you need to add that to the navigation controller's view (as a background color), and have the child view controller's views be transparent (or partially so). This code in the navigation controller's root view controller will add the background:
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationController.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"img.tiff"]];
}
I know exactly what you're talking about and I'm actually doing the same with my current project.
I accomplished this by using Interface Builder and a single view controller. Basically I placed a UIImageView in the view and set it to the background you wish, then I put a transparent UIScrollView on top of it. Inside that scroll view I put the two views I want to scroll horizontally through.
Don't forget to enable UIScrollView paging. In my case, I had two table views. Starting from the first one, if you swiped from right to left it would scroll to the next table view, and if you swiped left to right it would scroll back to the first.

Use objectAtIndex:indexPath.row selection to change a scrollview image

I am developing an iOS app that requires the user to search a list in a secondary view, select an entry in the list, and this then closes the view, and adjusts the mainViewController scrollview image to a specific location.
I have stored the selected entry in a variable, but I can't get the view to close, or figure out how to reset the scrollview using my variable. Any help is welcome.
Where you save the selection, set the mainViewController's content offset.
Then if you displayed your secondary view by [view addSubView:]
Call [secondViewController.view removeFromSuperView];
How are you displaying the view you want to close. If you are using
[self.view addSubview:someView] then you can call [someView removeFromSuperview];. If your problem is that your trying to have the view close its self, you can create a function - (void)closeSomeView in your main viewController that closes the view.
As for adjusting the scrollView you just need to create a CGPoint and do something like this
CGPoint somePoint = CGPointMake(xPosition, yPosition);
[scrollView setContentOffset:somePoint];

Resources