Gap between two connected UIViews with cornerRadius while animating - ios

I want to create a tipsView with a pop animate like this:
tips
But as the gif show, there is a very thin gap between the two connected view while animating;
Then I made a demo to find out the main cause and finally got the cornerRadius property. Here is demo code:
- (void)viewDidLoad {
[super viewDidLoad];
self.containerView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 214, 40)];
[self.view addSubview:self.containerView];
self.subView1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 214, 34)];
self.subView1.backgroundColor = [UIColor grayColor];
self.subView1.layer.cornerRadius = 6.0;
self.subView1.layer.masksToBounds = YES;
[self.containerView addSubview:self.subView1];
self.subView2 = [[UIView alloc] initWithFrame:CGRectMake(100, 34, 14, 6)];
self.subView2.backgroundColor = [UIColor darkGrayColor];
[self.containerView addSubview:self.subView2];
self.containerView.transform = CGAffineTransformMakeScale(0.01, 0.01);
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(tap:)];
[self.view addGestureRecognizer:tap];
}
- (void)tap:(UITapGestureRecognizer *)sender {
[UIView animateWithDuration:10 animations:^{
self.containerView.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
[UIView animateWithDuration:10 animations:^{
self.containerView.transform = CGAffineTransformMakeScale(0.01, 0.01);
}];
}];
}
The gif:
demo
and once I delete the line which used to set the cornerRadius property(or just set to 0), its behavior was in line with expectations. The gif after deleting:
demo after deleting
I wander why the cornerRadius property cause this result, and how I can fix it.
I find a similar question and the solution here, but I don't want to combine two views into one with bezier curve.

Related

Subview not moving along with its superview

I've done this a million times before but finding myself confused now.
When you animate a container view to change its position, its subviews move along with it don't they? You don't change subviews' frames you just change superview's frame because all subviews' positions inside their superview don't change.
But for some reason this time the subviews would not move along with their superview, it'd stay stuck at its original position.
- (void)writeCommentTapped{
UIView *writeCommentView = [[UIView alloc]init];
writeCommentView.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview: writeCommentView];
[self.view bringSubviewToFront:self.navView];
self.writeCommentTextView = [[UITextView alloc]init];
self.writeCommentTextView.backgroundColor = [UIColor blackColor];
[writeCommentView addSubview:self.writeCommentTextView];
[self.writeCommentTextView becomeFirstResponder];
self.writeCommentTextView.returnKeyType = UIReturnKeyDefault;
writeCommentView.frame = CGRectMake(0, -self.view.frame.size.height, self.view.frame.size.width, self.view.frame.size.height - self.keyboardSize.height);
self.writeCommentTextView.frame = CGRectMake(0, 0, writeCommentView.frame.size.width - 40, writeCommentView.frame.size.height - 100);
self.writeCommentTextView.center = writeCommentView.center;
[UIView animateWithDuration:0.15
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
writeCommentView.frame = CGRectMake(0, 0, writeCommentView.frame.size.width, writeCommentView.frame.size.height);
} completion:^(BOOL finished){
if (finished) {
}
}
];
}
Remove self.writeCommentTextView.center and set calculated frame for center
-(void)writeCommentTapped{
UIView *writeCommentView = [[UIView alloc]init];
writeCommentView.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview: writeCommentView];
[self.view bringSubviewToFront:self.navView];
self.writeCommentTextView = [[UITextView alloc]init];
self.writeCommentTextView.backgroundColor = [UIColor blackColor];
[writeCommentView addSubview:self.writeCommentTextView];
[self.writeCommentTextView becomeFirstResponder];
self.writeCommentTextView.returnKeyType = UIReturnKeyDefault;
writeCommentView.frame = CGRectMake(0, -self.view.frame.size.height, self.view.frame.size.width, self.view.frame.size.height - self.keyboardSize.height);
writeCommentView.frame = CGRectMake(0, -self.view.frame.size.height, self.view.frame.size.width, self.view.frame.size.height);
self.writeCommentTextView.frame = CGRectMake(40/2, 100/2, writeCommentView.frame.size.width - 40, writeCommentView.frame.size.height - 100);
// self.writeCommentTextView.center = writeCommentView.center;
[UIView animateWithDuration:0.15
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
writeCommentView.frame = CGRectMake(0, 0, writeCommentView.frame.size.width, writeCommentView.frame.size.height);
} completion:^(BOOL finished){
if (finished) {
}
}
];
}
OR
self.writeCommentTextView.center = CGPointMake(writeCommentView.frame.size.width/2.0, writeCommentView.frame.size.height/2.0);

Disable font animation in UIButton [duplicate]

This question already has answers here:
How to stop unwanted UIButton animation on title change?
(24 answers)
Closed 4 months ago.
I am animating a view that is sliding down. In the view there is a simple UIButton. The view and the button have fixed widths and heights (I checked with adding a color as background). Although when use:
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
//Slide Down the notification
CGRect notificationsRect = self.notificationContainerView.bounds;
notificationsRect.origin.y = 0;
notificationViewController.view.frame = notificationsRect;
} completion:^(BOOL finished) {
[notificationViewController didMoveToParentViewController:self];
self.currentNotification = notificationViewController;
}];
then the view slides down perfectly, expect for that the text in the UIButton kind of fades in. It starts really small and animates to the correct font size.
How can I disable the animation of the text in the UIButton?
Is the effect you have something similar to what is below? I tried to imitate your situation by having a view with a UIButton inside with some some text set for the title of the button. I then animated the button similarly to the way you did. As you can see there isn't really a fade happening on the text of my button inside my view that is sliding so I wonder if there is something else at play for you. I have the code I used below also to mock the situation.
- (void)viewDidLoad {
[super viewDidLoad];
self.myView = [[UIView alloc] initWithFrame:CGRectMake(200, 0, 100, 100)];
self.myView.backgroundColor = [UIColor greenColor];
UIButton *myButton= [[UIButton alloc] initWithFrame:CGRectMake(10, 0, 80, 80)];
myButton.backgroundColor = [UIColor blueColor];
[myButton setTitle:#"fun times" forState:UIControlStateNormal];
[self.myView addSubview:myButton];
[self.view addSubview:self.myView];
UIButton *resetButton = [[UIButton alloc] initWithFrame:CGRectMake(300, 300, 50, 50)];
resetButton.backgroundColor = [UIColor blackColor];
[resetButton addTarget:self action:#selector(reset) forControlEvents:UIControlEventTouchUpInside];
UIButton *goButton = [[UIButton alloc] initWithFrame:CGRectMake(300, 100, 50, 50)];
goButton.backgroundColor = [UIColor redColor];
[goButton addTarget:self action:#selector(go) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:goButton];
[self.view addSubview:resetButton];
}
- (void)reset {
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
//Slide Up the notification
CGRect notificationsRect = self.myView.bounds;
notificationsRect.origin.y = 0;
notificationsRect.origin.x = 200;
self.myView.frame = notificationsRect;
} completion:nil];
}
- (void)go {
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
//Slide Down the notification
CGRect notificationsRect = self.myView.bounds;
notificationsRect.origin.y = 200;
notificationsRect.origin.x = 200;
self.myView.frame = notificationsRect;
} completion:nil];
}
Disable animations for UIButton using setAnimationsEnabled:(BOOL)enabled
Reference:https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/index.html#//apple_ref/occ/clm/UIView/setAnimationsEnabled:

How to add subview with flip animation?

If you create a brand new single view app and put this code behind a button:
UIView *blah = [[UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];
blah.backgroundColor = [UIColor grayColor];
[UIView transitionWithView:blah duration:1
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[self.view addSubview:blah];
}
completion:^(BOOL finished){
}];
The subview is added immediately with no animation. If you add the subview first then try to animate it... you get the same problem.
UIView *blah = [[UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];
[self.view addSubview:blah];
[UIView transitionWithView:blah duration:1
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
blah.backgroundColor = [UIColor grayColor];
}
completion:^(BOOL finished){
}];
How on Earth do you animate a flip for a subview while or immediately after adding it?
You generally need to have the container that constrains the animation to be in place already:
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect frame = CGRectMake(0, 0, 100, 100);
_container = [[UIView alloc] initWithFrame:frame];
_container.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:_container];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UIView *subview = [[UIView alloc] initWithFrame:_container.bounds];
subview.backgroundColor = [UIColor darkGrayColor];
[UIView transitionWithView:_container
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[_container addSubview:subview];
}
completion:NULL];
}
This is worth a try:
UIView *blah = [[UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];
blah.backgroundColor = [UIColor grayColor];
[self.view addSubview:blah];
blah.alpha = 0.0; //Or with blah.hidden = TRUE and then FALSE inside the animation block
[UIView transitionWithView:blah
duration:1
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
blah.alpha = 1.0;
}
completion:^(BOOL finished){
}];

Removing subviews when bar button is tapped

I am trying to trigger adding two subviews when a Bar Button is tapped. But adding the subviews works just fine, but when I try removing the subviews, it doesn't work.
Here is the code I am implementing
-(IBAction)showPopover:(id)sender{
UIView *popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 100)];
UIView *popoverViewBackground = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 1000)];
popoverView.alpha = 0.0;
popoverView.layer.cornerRadius = 2;
popoverView.layer.borderWidth = 0.1f;
popoverView.layer.backgroundColor = [UIColor whiteColor].CGColor;
popoverView.layer.masksToBounds = YES;
popoverViewBackground.layer.backgroundColor= [UIColor blackColor].CGColor;
if (popoverCount == 0) {
[self.view addSubview:popoverViewBackground];
[self.view addSubview:popoverView];
popoverCount = 1;
}else if (popoverCount ==1){
[popoverView removeFromSuperview];
[popoverViewBackground removeFromSuperview];
popoverCount = 0;
}
[popoverViewBackground setAlpha:0.5];
[popoverView setAlpha:1.0];
}
Problem is that you are creating new view every time you click the button so old view not removing put your code like thi, then it will work fine.I have tested it.
in .h file
#interface secondViewController : UIViewController
{
int popoverCount;
UIView *popoverView ;
UIView *popoverViewBackground;
}
in .m file
- (void)viewDidLoad
{
[super viewDidLoad];
popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, -100, 320, 100)];
popoverViewBackground = [[UIView alloc] initWithFrame:CGRectMake(0, -100, 320, 100)];
popoverView.alpha = 0.0;
popoverView.layer.cornerRadius = 2;
popoverView.layer.borderWidth = 0.1f;
popoverView.layer.backgroundColor = [UIColor whiteColor].CGColor;
popoverView.layer.masksToBounds = YES;
popoverViewBackground.layer.backgroundColor= [UIColor blackColor].CGColor;
}
-(IBAction)showPopover:(id)sender {
if (popoverCount == 0) {
[self.view addSubview:popoverViewBackground];
[self.view addSubview:popoverView];
[UIView animateWithDuration:0.5
animations:^{
popoverView.frame = CGRectMake(0,0,320,100);
}
completion:^(BOOL finished){
;
}];
[UIView animateWithDuration:0.5
animations:^{
popoverViewBackground.frame = CGRectMake(0,0,320,100);
}
completion:^(BOOL finished){
;
}];
popoverCount = 1;
}else if (popoverCount ==1){
[UIView animateWithDuration:0.5
animations:^{
popoverView.frame = CGRectMake(0,-100,320,100);
}
completion:^(BOOL finished){
[popoverView removeFromSuperview];
}];
[UIView animateWithDuration:0.5
animations:^{
popoverViewBackground.frame = CGRectMake(0,-100,320,100);
}
completion:^(BOOL finished){
[popoverViewBackground removeFromSuperview];
}];
popoverCount = 0;
}
[popoverViewBackground setAlpha:0.5];
[popoverView setAlpha:1.0];
}
UIView *popoverView;
UIView *popoverViewBackground;
Declare popoverView and popoverViewBackground in .h file and allocate and initializes of these subview in when popoverCount is zero.
-(IBAction)showPopover:(id)sender{
if (popoverCount == 0) {
popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 100)];
popoverViewBackground = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 1000)];
popoverView.alpha = 0.0;
popoverView.layer.cornerRadius = 2;
popoverView.layer.borderWidth = 0.1f;
popoverView.layer.backgroundColor = [UIColor whiteColor].CGColor;
popoverView.layer.masksToBounds = YES;
popoverViewBackground.layer.backgroundColor= [UIColor blackColor].CGColor;
[self.view addSubview:popoverViewBackground];
[self.view addSubview:popoverView];
popoverCount = 1;
}else if (popoverCount ==1){
[popoverView removeFromSuperview];
[popoverViewBackground removeFromSuperview];
popoverCount = 0;
}
[popoverViewBackground setAlpha:0.5];
[popoverView setAlpha:1.0];
}
At least 2 issues in your code:
Every time the method is involved, you are creating new instances of these sub-views
You are removing the newly created instances. That is, previous instances that were added still exist.
You should
save these sub-views in instance variables, so that you can refer to them and remove them correctly.
move the creation code inside the first if-block, so that you are not creating too many sub-views.
It is happening because you are applying addSubview and removeFromSuperview on different object.
When First time showPopover is called it create two object of UIView
with name popoverView and popoverViewBackground.
and add this to self.view.
Till now every thing fine but when this method call second time
New object of popoverView and popoverViewBackground created again and
You are trying to remove that new created object from self.view which is not there.
How to solve this:
There are two way to solve this:
1) Create this object in .h file so you can access it from anywhere.
2) create object in such way that it created only when method call first time.
Give this UIView tag and when you remove find this tag in UIView.subview
Way 1 is easy way 2 require some code but you can make it efficient in turm of memory.
All the best

How to fit image in UITextView and Tap to get larger

I have created a Table-view in main ViewController once i touch the row it will take to the next view controller(DetailViewController) where it display the image and name of dish.And once i tap the image it should get larger but it is not getting bigger .The below code is which i have tried in DetailViewController.
DetailViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
imageView=[[UIImageView alloc] initWithFrame:CGRectMake(10, 10,100, 100)];
CGRect textViewFrame = CGRectMake(10, 10, 300, 400);
textView = [[UITextView alloc] initWithFrame:textViewFrame];
textView.returnKeyType = UIReturnKeyDone;
textView.backgroundColor=[UIColor whiteColor];
textView.editable=NO;
textView.delegate = self;
[self.view addSubview:textView];
[textView addSubview:imageView];
textView.alpha = 0.9;
textView.font = [UIFont systemFontOfSize:15];
if(mrowno==0)
{
imageView.image=[UIImage imageNamed:#"Dosa.jpg"];
textView.text = #"\n\n\n\n\n\n\n\nDOSA\nDosa, ";
imageButton = [[UIButton alloc]init];
[imageButton setFrame:CGRectMake(0, 0, 100, 100)];
[imageButton addTarget:self action:#selector(imageTapped:) forControlEvents:UIControlEventTouchUpInside];
[imageView addSubview:imageButton];
}
Here is the method to make image larger
-(void)imageTapped:(UIButton*)in_sender
{
[UIView transitionWithView:in_sender.superview duration:0.8f options:UIViewAnimationOptionCurveLinear animations:^
{
[in_sender.superview setFrame:CGRectMake(0, 0, 300, 500)];
}
completion:^(BOOL finished)
{
}];
}
You can increase and decrease the size of image by pinch in and pinch out,If it required
-(void)viewDidLoad
{
UIPinchGestureRecognizer* pinch=[[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(pinching:)];
[self.imageView addGestureRecognizer:pinch];
}
-(void)pinching:(UIGestureRecognizer*) recognizer
{
UIPinchGestureRecognizer* pinch=(UIPinchGestureRecognizer*) recognizer;
self.imageView.transform=CGAffineTransformScale(self.imageView.transform, pinch.scale, pinch.scale);
pinch.scale=1;
NSLog(#"pinching");
}
You do not want to use transitionWithView. Instead, you want to use + animateWithDuration: delay:options:animations:completion: (or any of its shorter variants...)
[UIView animateWithDuration:0.3f delay:0.0f options:UIViewAnimationOptionCurveEaseInOut animations:^{
viewYouWantToAnimate.frame = CGRectMake(..., ..., ..., ...);
} completion:^{
//Add completion code here, or pass nil if you don't have anything to do.
}];
Edit: In case you were wondering what transitionWithView was used for... the AppleDocs have a great example of it adding animations for remove/addSubview methods (not frame modifications):
[UIView transitionWithView:containerView
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
[fromView removeFromSuperview];
[containerView addSubview:toView];
} completion:NULL];

Resources