UIView clipToBounds is not stopping a subView receiving touches outside the parent view - objective-c

I have two UIViews. I'm using one to contain the other so that I can slide one inside the other. I'm encountering an issue where even though a subView is clipped to the bounds of its parent, it is still receiving touch events and blocking access to other underlying views.
I have three screenshots that show the layout. I've coloured the parent green and the child red.
The idea is that the user clicks "View" and the subView slides up. When the subView is in the default position, the UITabBar is covered and cannot be clicked. You can see this in the first image where the red view is present at the bottom. When the subView is moved to the top, the UITabBar can be clicked as it's now visible. In the third image, I've show what it's like with clipToBounds enabled on the green UIView.
I've enabled clipToBounds, so I cannot understand why the subView is blocking the underlying UITabBar. Is my understanding of clipToBounds completely wrong??

Using clipToBounds only affects the visual layout of a subView, not the logical layout. This means that whilst my subView isn't visible to the eye, it's visible to touch.
I've worked around this issue by animating the size of the subView rather than its position. In my code below, the stationProximityView is the subView. I animate its size by 40 pixels to bring the black title back into view.
[UIView beginAnimations:#"stationProximityBar" context:NULL];
self.stationProximityView.view.frame = CGRectOffset(self.stationProximityView.view.frame, 0, -40);
[UIView commitAnimations];
When I no longer need it, I animate it out of view.
[UIView beginAnimations:#"stationProximityBar" context:NULL];
self.stationProximityView.view.frame = CGRectMake(0 ,0, 320, 500);
[UIView commitAnimations];
If the user taps the view button, the entire subView is shown:
[UIView beginAnimations:#"stationProximityBar" context:NULL];
self.stationProximityView.view.frame = CGRectMake(0,460,320,40);
[UIView commitAnimations];
Dismissal causes the view to be hidden in the same way as the small bar.
[UIView beginAnimations:#"hideStationProximityBar" context:NULL];
self.stationProximityView.view.frame = CGRectMake(0,0,320,500);
[UIView commitAnimations];
At the moment, this code is only being tested on the iPhone 5, so the hard-coded height of 500 would causes issues on previous iPhone models.

Related

Change background colour BEHIND ViewController frame (when frame.origin is altered)?

I have an app which intakes client details, built for iPad. When the user taps a UITextField towards the bottom half of the ViewController, the frame programatically shifts upwards so that the fields aren't hidden behind the keyboard. (I tried to implement a UIScrollView but just cannot seem to get it working.) The slight issue I'm having now is when the frame shifts up, you can vaguely see the black behind it. This isn't a huge issue because I have changed the animation time and the black background is barely visible, but I have a feeling there is a more elegant solution.
Here is my code to shift the frame:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
// Animate frame up if lower textfields are tapped
if (([textField isEqual:_emailField]) || ([textField isEqual:_dobField]) || ([textField isEqual:_niNumField])) {
[UIView beginAnimations:nil
context:NULL];
[UIView setAnimationDuration:0.35f];
CGRect frame = self.view.frame;
frame.origin.y = -210;
[self.view setFrame:frame];
[UIView commitAnimations];
} else {
// Return frame to original position if other textfields are tapped
[self dismissKeyboard];
}
return YES;
}
- (void)dismissKeyboard {
[UIView beginAnimations:nil
context:NULL];
[UIView setAnimationDuration:0.15f];
CGRect frame = self.view.frame;
frame.origin.y = 0;
[self.view setFrame:frame];
[UIView commitAnimations];
}
Here is a brief screenshot of what I'm trying to describe. Left picture is the ViewController normally, right picture is when the frame has been shifted upwards. You can see (vaguely) almost in line with the second row of characters is where the frame stops.
I realise this doesn't seem like an issue because it is barely visible at all, but I have had to speed up the animation hiding the keyboard or else the frame drags behind and the black background becomes visible. I am wondering: is there a way to change this colour? Or is that something we don't have access to? If anyone can suggest a more elegant method for what I am trying to do, I'd gladly take a better solution. Thanks in advance.
Your UIViewController's view is added to the main UIWindow. So you should be able to achieve what you want by changing the UIWindow's background color.
In the UIApplicationDelegate:
self.window.backgroundColor = [UIColor whiteColor];
However, what you're doing isn't the best way to solve the problem of the keyboard covering up the text fields. You should use a UIScrollView or a UITableView to manage this view and use content insets to shift the view up or down.

Get current frame of UIView while animated

I have a UIView and I want to get it's current frame while it's animated.
I am using a basic animation:
[UIView beginAnimations:#"MoveView" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDuration:3];
_testView.frame = CGRectMake(0, 100, 40, 40);
[UIView commitAnimations];
and I have a button which should add another UIView at the current position of the first one while animated, but when I press the button, it adds it to the end position of the animation...
Any suggestions?
Thank you in advance!
Most probably you're setting the newly added UIView properties based on the animated view's modelLayer. Let's try to setup the UIView properties based on the animated view's presentationLayer:
The layer object returned by this method provides a close approximation of the layer that is currently being displayed onscreen. While an animation is in progress, you can retrieve this object and use it to get the current values for those animations.
CALayer Class Reference

UITextView not Responding to Touch Events after Animation

I am performing an animation to correctly keep the UITextView at the bottom of the screen if I expand the view. For some reason if I perform the animation, the UITextView stop responding to touch events, so there is no keyboard that will show up.
All I am doing is:
CGRect newSendTextView = self.commTextView.frame;
newSendTextView.origin.y = (newSendTextView.origin.y + (height - self.defaultSize.size.height));
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:.5];
self.commTextView.frame = newSendTextView;
[UIView commitAnimations];
I know the UITextView is still on the screen after I do the transformation since I colored the UITextView background a bright blue, but it doesn't want to respond to any touch events.
If I comment out self.commTextView.frame = newSendTextView; so that it doesn't move, the touch events register.
I have no idea why this happens, I tried
[self.commTextView becomeFirstRespond];
and I have checked if isEditable and isUserInteractionEnabled is set to 1 and it is.
I guess, new position of TextView might be getting overlayed by other view. Check any other View is having same frame on your TextView new position. Use clipsToBounds property to find it.

Flip UIView (reversi style)

I'm trying to make a reversi game, and want to flip a piece to the opposite color. So when a white piece is flipped, it becomes black, and the other way around.
I know you can flip a UIView with the code below, but can't figure out how to flip it to another image.
In my "Piece" class, I have a UIButton with the black or white image. Do I need to create two buttons, and then flip them somehow?
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:card cache:YES];
Thanks in advance
I would do this to do a transition from the white button to the black button in 0.4s.
You need to have your white and black buttons already as subviews of some other view. For this transition the black button should be hidden before doing the transition.
UIViewAnimationOptionShowHideTransitionViews says that your fromView will be hidden after the transition.
The flip will occur in the whiteButton superview.
[UIView transitionFromView:whiteButton
toView:blackButton
duration:0.4f
options:UIViewAnimationOptionTransitionFlipFromRight |
UIViewAnimationOptionShowHideTransitionViews
completion:^(BOOL finished){}];

UIColor groupTableViewBackgroundColor is transparent

I have a grouped style UITableView on my navigation stack, and when I click on a cell, I push a UIDatePicker onto the stack. The problem is that I want this custom view to have the same background color as my table view.
I tried setting the background color of my custom view like:
datePicker.backgroundColor = [UIColor groupTableViewBackgroundColor];
But this comes out transparent. I also tried modifying the underlying CGColor object to have an alpha of 1.0, which caused the background color to be black.
The following does work as expected:
datePicker.backgroundColor = [UIColor lightGrayColor];
But, of course, this color doesn't quite match the grouped table background color.
Am I going about this all wrong? I found a similar post about this here, but no helpful response.
What do you mean you "push a UIDatePicker onto the stack"? Why dont you try animating the UIDatePicker into view?
when the view loads, create the picker and set the frame off screen, such as
[picker setFrame:CGRectMake(0,960,320,216)];
then instead of "pushing" the picker, animate it into view like:
[UIView beginAnimations:nil context:NULL];
[picker setFrame:CGRectMake(0,200,320,216)];
[UIView commitAnimations];
And when you want to dismiss the picker, just hide it like:
[UIView beginAnimations:nil context:NULL];
[picker setFrame:CGRectMake(0,960,320,216)];
[UIView commitAnimations];
If you need to, you can also add a toolbar with a "done" button to dismiss the picker, works great for me.
If the contents of the picker are going to be displayed on the table, then you can set the frame of the table in that animation sequence. in the first one, make the table half the size (like 150 for my example would work perfect), then in the hide sequence, make the table the original size (415 for this example). And when you hide the picker, call [tableView reloadData]; to refresh the table.