How can I flip between two UIView? - objective-c

I'm using two UITextView objects. Each UITextView represents the side of a single card in a flash card application. Just like when using regular flash cards, I want the user to have the ability to flip a card. I am asking how to flip between two UIView objects because UITextView are UIView subclasses so the same idea should work.
The animation I am looking for looks like this.
The only problem with the above example is that it utilizes two UIViewController objects and UITextView is not a subclass of UIViewController so the same principle does not apply.
Any ideas on how to do the flip animation?

You can use the UIView class method +transitionFromView:toView:duration:options:completion: to accomplish this. Both your text views need to be descendants of a common superview. Use the option UIViewAnimationOptionTransitionFlipFromLeft (or ...FromRight) to get a horizontal flip.

Looks like your question has been answered already here, just tweak the transform to make it a horizontal instead of vertical flip:
- (void)horizontalFlip {
[UIView animateWithDuration:someDuration animations:^{
yourView.layer.transform = CATransform3DMakeRotation(M_PI, 0.0, 1.0, 0.0);
} completion:^(BOOL finished){
// code to be executed when flip is completed
}];
}
As explained in that linked question, you can further modify this to do half the flip by using M_PI_2, then in the completion block of the first animation swap out the UITextViews and start a new animation to finish the flip.
Don't forget to #import math.h and #import <QuartzCore/Quartz.h> at the top of your file!

you can first hide the one UITextView and Show the another UITextView. To flip it, you can hide the displayed UITextView and show the hidden UITextView. You can also use animations explained here for it to create a flip effect.

Related

Make a UITableView that is not 100% width

I would like to make a grouped UITableView where the cells are not 100% width, this is because I want to show the background, and each cell will have rounded corners.
Sort of like this;
However, I'm not sure how to do this using Storyboard; or is it only something you can do in code?
Ideally, I'd like the whole area scrollable; but make the cells appear less than 100% width
One possibility: you could use a container view. That is, in the view controller where you want this table view to appear, add a Container View in interface builder and set the size however you like. Then add a UITableviewController to your storyboard. Embed the UITableviewController in the Container View by control dragging from the Container View to the UITableviewController and selecting embed.
i think you can use customized cells, set special backgrounds (with rounded corners etc.) and replacing views to have a padding to the borders. but not sure if it really works well. in the example you would have 3 different cells in one section.
Not sure if this is the best solution; the one I have so far is...
In storyboard
Create UITableView as normal as child of a UIView, set up
delegates, data source as required
Add a UITableViewCell to this
Create my own custom subclass of UITableViewCell;
- (void)setFrame:(CGRect)frame {
frame.origin.x += kInset;
frame.size.width -= 2 * kInset;
[super setFrame:frame];
}
-(void) drawRect:(CGRect)rect {
[self.layer setCornerRadius:kCornerRadius];
[self.layer setMasksToBounds:YES];
}
The constants are just any number for now, say 10
Next I ensure my UITableViewCell is pointing to this subclass.
Now my cells appear with a margin and the uitableview itself is 100% width.
I will have to keep playing around with it; maybe there is a better solution

Cocoa-Touch - Chain animations together

This probably sounds harder than it is. I'm actually trying to chain some animations together to make it look smooth. What I'm doing is some basic animation of a UIPickerView that slides from the bottom of the screen and when it is dismissed it slides back to the bottom of the screen. I handle this functionality in two methods - (void)showPicker and - (void)hidePicker
Directly after the picker has been hidden I want to show the keyboard, but I don't want to show the keyboard before the picker has been hidden.
Also I want to this the other way around, directly after the keyboard has been hidden I want to show the UIPickerView. I know I can observe notifications of UIKeyboardDidShowNotification and UIKeyboardDidHideNotification
So what would be the best way to deal with this so that these animations are chained together in a smooth way?
For the path picker->keyboard try
[UIView animateWithDuration:0.3
animations:^{
[self hidePicker];
}
completion:^(BOOL finished){
[yourInputView becomeFirstResponder];
}];
The other way around listen to UIKeyboardDidHideNotification and invoke showPicker in the callback.
Do you show your picker as a way to input some info in a field or something?
If so, you better use the inputView property of UITextField so that it behaves quite like a normal TextField but uses your UIPickerView instead of the standard keyboard.
That's the standard way to do this (showing a picker in place of the keyboard) and you won't have to bother about chaining animations.

Change layer of images

Is there a way to change the "layer" that UIImageView objects are drawn in? Whenever I add an image view to a view controller it defaults to drawing the most recently added one on top of all the others. So if I decide to add a "background" image it is now a "foreground" image and blocks everything else.
There isn't anything in the IB options or in the UIImageView class reference and I haven't been able to find anything here on SO. It's been a problem for a while and it's weird that I haven't seen anything about it before... I think it might just be my semantics coming from a delphi background.
Anyway, does anyone know about this issue / ICANHAZTEHCODEZ to fix it? Or is this just like the UIScrollView problem and poorly supported by the development environment.
This happens when I try to use the editor to arrange the subviews.
You can bring a SubView to Front or Send it background programmatically using
[self.view bringSubviewToFront:yourImageView];
and
[self.view sendSubviewToBack:yourImageView];
when self.view must be the superview of your imageView
In IB, select a UIControl and from top menu bar select Editor->arrage->send to front or back
When you use UIView's addSubview: method, it will add it to the top of the view stack resulting in what you are seeing.
There are numerous other UIView methods you can use to determine the order of subviews. E.g.:
- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview;
- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index;
- (void)sendSubviewToBack:(UIView *)view;
- (void)bringSubviewToFront:(UIView *)view;

Cause UIScrollView zoomToRect: to only display a portion

I have a UIScrollView subclass that contains a UIImageView. When the user double taps on the zone I want to zoom to that CGRect (calculated from CGPoint) and "hide" the rest of the UIImageView. The final effect is similar in Mavel.app and The Walking Dead.app when you are reading a comic.
Until now I got:
-(void)presentRect:(CGRect)rect {
self.bounds = originalFrame; //1
[UIView beginAnimations:#"navigateToPos" context:nil];
[self zoomToRect:rect animated:NO];
self.bounds = rect;
[UIView commitAnimations];
}
This works, but "zoomToRect" needs the whole bounds of the UIScrollView and when I restart it (line 1), it gives an undesired effect.
I am stuck with this. I don't know if I need a new approach or need to use another property of UIScrollView.
Any help is appreciated. Thanks.
I downloaded this apps to see it. I'm almost sure they didn't even use uiscrollview. The way the pages moves make me think about that. And uiscrollview should be used only when you really need it, because it have a lot issues when you're customizing. (tiled content, zooming and others problems).
Slide to a next page only 50px aprox., the page goes to the next, in uiscrollview it didn't happen because it works diff.
As I said before, probably it's made using 4 bars (as you correct me) or it can be done with a view wrapping the uiimage and working as a mask. You only need calculate the size of the zoom square and move it to center, and resize the wrapper view to fit this new size. The substitute for the uiscrollview for pages can be a simple image gallery, but where is images you put this "comic-view".
I've solved using other properies from UIScrollView simulating the desired effect.

What's the proper way to use animation in a UIViewController with several discrete subscreens?

I'm writing an app where one component is a checklist screen. The checklist has 4 or 5 logical subsections and I want to display each section as a separate view, with the user switching between views with forward and back buttons (and eventually with a swiping gesture event but that's a separate issue).
Currently, I have a UIViewController class for managing the checklist logic, which loads the initial view from a xib. The xib contains all of the 4 or 5 views, and I can currently fairly easily switch between them just by setting up references to all the UIView objects in the UIViewController and calling
[self setView:viewNumberX];
within that class. However, this just abruptly switches the view, and doesn't have the nice iOS-style animation.
The reason I did it this was was because I thought the proper paradigm was to have one UIViewController managing one or several distinct related views - in this case, my one UIViewController is managing all 4 or 5 subviews because they are all parts of the same checklist subject to the same checklist logic. I do notice that there's a presentModalViewController:(UIViewController*)animated:BOOL method defined for UIViewControllers that does allow me the option of animating as I switch views, but this seems to require that I wrap my UIViews in 4 or 5 separate UIViewControllers, which doesn't make sense to me. The individual views don't have their own logic. Is there another way to get this functionality, or am I approaching this the wrong way?
If you are set about not having a UIViewController for each UIView, you can fix the animation bit using beginAnimations:context: and commitAnimations. Basically you use them like this, e.g.:
[UIView beginAnimations:#"animationName" context:nil];
[UIView setAnimationDuration:0.80];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight
forView:self.navigationController.view cache:NO];
...<change view>...
[UIView commitAnimations];
Actually, if you are targeting iOS 4, you are required to use animateWithDuration:animations:, but the concept remains the same. Here you will find a code snippet to do the flip with the latter.
If you want to have checklists you can swipe through, you can avoid both gestures and animations by using UIScrollView with pagingEnabled set to YES. Make the scroll view as wide as screen, and make it's contentSize property as wide as screen * number of screens, then place each checklist inside that scrollview with x coordinate being something like padding + PageNumber * 320 (with pageNumber being an int and starting with 0). If you chose this approach I'm here if you need more details or sample code.