iOS Segue Animation Beginner with a query - ios

Okay guys/gals, here's what I'm looking to do, I'd love some pointers to a good tutorial or a good explanation on how to do this. As much as I'd love someone to post code here, I need to learn how to do this for future projects and overall feel good points.(I've searched myself but could only find swift tutorials which were similar but not the same)
Imagine a screen with a circular button in the middle, wait you don't have to
Sorry about the size, I want to press that button and perform a segue which expands from that button, eventually filling the screen with the new red screen. So in essence the button grows and fill the screen but really I'm transitioning to a new screen.
Any pointers greatly appreciated. Thanks.
A minor detail: this is the only screen on storyboard at present

I had to do a couple of non-obvious things to make this work. First, get rid of button constraints in the storyboard. Second, add a line to my viewDidLoad to derive constraints.
- (void)viewDidLoad {
[super viewDidLoad];
self.redButton.translatesAutoresizingMaskIntoConstraints = YES;
}
Then, for the actual effect I create an animation when the button is pressed. The animated:NO bit in the completion handler prevents extra visual noise.
- (IBAction)redButtonTapped:(id)sender {
[UIView animateWithDuration:3.0 animations:^{
self.redButton.frame = self.view.frame;
} completion:^(BOOL finished) {
UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"redController"];
[self presentViewController:vc animated:NO completion:nil];
}];
}
I used a simple button object for this. To make it work with a round image, you may have to play with the new frame size a bit.

Related

Custom iOS navigation controller animation : is this wrong?

I've been asked to add a fully custom transition between two UIViewControllers and came up with this solution. It works, but I don't know if there's a better / more elegant way to do it.
By fully custom, I mean involving modifying the first view controller subviews (moving them, not only fading or whatever), being able to change the duration, etc.
I'd like to know two things :
Can this be broken up in any way ? Some problem I might have forgotten maybe ?
Do you think this is ugly ? If so, is there a better solution ?
As a few lines of code is better than a thousand words, here is a very simple example to get the idea :
// Considering that self.mainView is a direct subview of self.view
// with exact same bounds, and it contains all the subviews
DCSomeViewController *nextViewController = [DCSomeViewController new];
UIView *nextView = nextViewController.view;
// Add the next view in self.view, below self.mainView
[self.view addSubview:newView];
[self.view sendSubviewToBack:newView];
[UIView animateWithDuration:.75f animations:^{
// Do any animations on self.mainView, as nextView is behind, you can fade, send self.mainView to wherever you want, change its scale...
self.mainView.transform = CGAffineTransformMakeScale(0, 0);
} completion:^(BOOL finished) {
// Push the nextViewController, without animation
[self.navigationController pushViewController:vc animated:NO];
// Restore old
self.backgroundImageView.transform = CGAffineTransformIdentity;
}];
I've double checked a few things that I thought might get wrong :
After the push, the view hierarchy isn't broken, everything looks fine, self.view suffer any changes
When poping, nextView isn't in self.view any more.
Thanks for your opinions.
There are differents way to make a transition between ViewControllers. Your code works but you can implement a more official way.
Use methode transitionFromViewController:toViewController:
Check the tutorial : http://www.objc.io/issue-1/containment-view-controller.html#transitions
Or you can use UIViewControllerContextTransitioning Check the tutorials : http://www.objc.io/issue-5/view-controller-transitions.html and http://www.teehanlax.com/blog/custom-uiviewcontroller-transitions/

UIScrollView Jerky Scrolling

I have a big scroll view. I just wish to scroll around the scroll view with fixed steps on every button press. However when I write the following code the scroll view scrolling is very jaggy. Can someone explain why?
CGPoint lstructCurrentPoint = self.objScrollView.contentOffset;
lstructCurrentPoint.x += 400;
[UIView animateWithDuration:1.0f
delay:0.0f
options:UIViewAnimationOptionCurveLinear
animations:^{
[self.objScrollView scrollRectToVisible:CGRectMake(lstructCurrentPoint.x,
lstructCurrentPoint.y,
self.objScrollView.bounds.size.width,
self.objScrollView.bounds.size.height)
animated:NO];
} completion:^(BOOL finished)
{
}];
I do not use the animated:Yes arguement because I need custom scroll speeds between the different contentOffsets.
when you update your scroolview content frame while scrolling with an animation is like you try to update something that is in the past that is already changed... (probably is not the best explanation :D )
try with this in your animation option:
options:UIViewAnimationOptionCurveLinear|UIViewAnimationOptionBeginFromCurrentState
Why don't you just try using
[self.objScrollView scrollRectToVisible:CGRectMake(lstructCurrentPoint.x, lstructCurrentPoint.y,self.objScrollView.bounds.size.width,self.objScrollView.bounds.size.height) animated:YES];
instead of using this within UIView animation function.
Try to use
[self.objScrollView setContentOffset: CGPointMame(lstructCurrentPoint.x, lstructCurrentPoint.y) animated: YES];
instead of scrollRectToVisible.
scrollRectToVisible animated is an animation by itself.
With your current code, you are trying to animate the animation.
Hence it is jerky.
Just use to scroll the rect to visible:
[self.objScrollView scrollRectToVisible:CGRectMake(lstructCurrentPoint.x,lstructCurrentPoint.y,self.objScrollView.bounds.size.width,self.objScrollView.bounds.size.height) animated:YES];
No one can properly answer your question without knowing what content you have in the scrollView.
However, you can find out what is causing this yourself.
Profile the app on your device. This will open Instruments. Select the Core Animation tool.
When the app is running scroll the view so that instruments captures the data.
Now the Time Profiler section will tell you exactly what is taking a long time. Fix this and you'll have smooth scrolling.

ios display views and viewcontrollers on part of the screen

I have this bug that I'm struggling with for a few days now. I basically want to make a profile much like Instagram has.
When you click on one of the first two buttons in the upper "tab bar" the content is displayed in the lower part. The upper part of the screen stays the same. I have some UIViewControllers and some UITableViewController. I have like 5 buttons that are suppose to display the viewcontrollers. My problem is that I can display a tableviewcontroller but if I try to display the second and then go back to the first, for instance, it gets stuck to the last one I displayed. I hope this is clear enough. here is the code for displaying the viewcontroller.
- (IBAction)wallButtonPressed:(id)sender
{
if(!_userWallViewController) {
self.userWallViewController = [[WallViewController alloc] init];
self.userWallViewController.activityFeedTableView.bounds = self.containerView.bounds;
}
[self.currentViewController.view removeFromSuperview];
[self.currentViewController removeFromParentViewController];
self.currentViewController = self.userWallViewController;
self.userWallViewController.searchURLString = [NSString stringWithFormat:#"/event/user/%#", self.userID];
self.userWallViewController.containerView = self.containerView;
[self.containerView addSubview:self.userWallViewController.view];
[self addChildViewController:self.userWallViewController];
[self.userWallViewController.view setNeedsDisplay];
[self.userWallViewController viewWillAppear:YES];
}
containerView is an UIView that takes the whole lower part of the screen. currentViewController is a placeholder viewController and userWallViewController is a UITableViewController.
Any kind of help is much appreciate. This is a real bugging situation. Thanks
I was doing a stupid mistake that was hard to identify bu #Matt's suggestion helped.
[self.fanOfViewController.containerView addSubview:self.fanOfViewController.userSimpleTableView];
[self.currentViewController.view removeFromSuperview];
[self.currentViewController removeFromParentViewController];
self.fanOfViewController.containerView = self.containerView;
[self addChildViewController:self.fanOfViewController];
[self.containerView addSubview:self.fanOfViewController.view];
//CLEAN UP THE CONTAINER VIEW BY REMOVING THE PREVIOUS ADDED TABLE VIEWS
[self.userWallViewController.activityFeedTableView removeFromSuperview];
[self.userFansViewController.userSimpleTableView removeFromSuperview];
Each time I was adding a new tableView from it's view controller by pressing the corresponding button I was stacking it in the current's view container. When I was trying to remove the corresponding viewController from the hierarchy and then add it again the viewDidLoad method was not called (it was only called the first time). The was where I had my logic of removing the tableView.
Now I'm also adding it when the button is pressed and remove the other tableViews from the "stack". It may not be the very best way but I do plan to optimize it. I hope this is clear enough and helps anybody that comes across this problem.

Animate UITextview change out, Keep keyboard in place

I have a UITextview, becomes first responder and keyboard is presented. Presently, I have buttons in inputAccessoryView toolbar that exchange the text forward and reverse through an array of strings.
I have the process working with no issues, so of course I am inclined to break it. My wish is to slide the textview left and right like a carousel to make it more clear to the user that next or previous string is coming and going. The current system simply replaces the text with no animation.
My first thought was to create a UINavigationController, give it an array of UIViewControllers that present the UITextviews. The navigation controllers view is only as big as the textview and I add it as a subview to my full view (which is itself in a navigation controller). I got this working fairly completely, the navigation bar is hidden and it looks no different than the original textview except that the textview now slides off to the right or left, depending if I am pushing or popping.
The problem with that is that the keyboard slides off along with the dismissed view controller, then the new textview in the new controller becomes first responder and the keyboard returns. Close, but no cigar.
I considered using page view controller but it seems it will have the same issue. I think I may have to go back to the single textview and animate the whole process directly with static screen grabs. That is completely beyond my experience level and I am think there must be a simpler way.
Can anyone suggest a simple way to keep that keyboard present while the views are swapped as described? Suggestions on other angles of attacking this?
Seems like an awful lot of overhead for a simple animation.
Try something like this (assuming ARC):
typedef enum _eDirection
{
rightToLeft = -1,
leftToRight = 1
} eDirection;
- (void) animateTextFields:(eDirection)direction
{
CGFloat distance = self.window.bounds.size.width;
UITextField *oldTextField = thisView.textField;
CGRect oldTFRect = oldTextField.frame;
CGRect newTFRect = CGRectOffset(oldTFRect, -direction * distance, 0);
UITextField *newTextField = [[UITextField alloc] initWithFrame:newTFRect];
[newTextField setText:#"whatever"];
[self addSubview:newTextField];
[UIView animateWithDuration:0.3f
animations:^{
[oldTextField setFrame:CGRectOffset(oldTextField.frame, direction * distance, 0)];
[newTextField setFrame:CGRectOffset(newTextField.frame, direction * distance, 0)];
} completion:^(BOOL finished) {
[self setTextField:newTextField];
[self removeSubview:oldTextField];
[newTextField becomeFirstResponder];
}];
}
(Disclaimer: as with all code typed off the top of one's head, etc., etc.)
This method would create a new textField, animate it horizontally onto the screen while moving the existing one off the screen in the direction you give, and then assigns the new textField as the current one and makes it the firstResponder.

I would like to use transitionFromView to flip in a new view and have my uiswitch that is on the second page, already be set, is this possible?

Edit: just to be clearer on what I am looking to do. I have 1 view with button on it. When you press the button a new view transisions in with a flip. On the new view their are two switched that I set through code after the user has clicked the button. What I want to happen is that the switches are in their final spots, before the new view flips in. What happens is the new view flips in, and then the UIswitches flicker into place.
This is the code I have. I have tried setting the uiswitch on viewwillappear and viewdidload, but each time it comes over with the default setting from IB and switched after the UIview transition is complete. I want the switch to be set already, so that once the view "flip" is done, there is no more movement on the screen. Thanks.
//set the uiswitch before the transision
[self.settingsPage.myUISwitchThing setOn:NO animated:NO];
//transition by flip
[UIView transitionFromView:self.view toView:self.settingsPage.view duration:1.0 options:UIViewAnimationOptionTransitionFlipFromRight completion:^(BOOL done ) {
[self.view removeFromSuperview];
Looks like the issue was that I was trying to animate the switch movement when I was setting the switch value in the viewdidload. setting animated:NO has resolved the issue in the iPhone simulator. hopefully it will fix it on the device when I can test it at home later.

Resources