I'm having some trouble with moving a view:
- (void)viewDidLoad {
CGRect newFrame = self.popUp.view.frame;
newFrame.origin.y = self.view.bounds.size.height;
self.popUp.view.frame = newFrame;
[[self view] addSubview:[self.popUp view]];
[super viewDidLoad];
}
This should put the subview popUp below the current screen but it does not seem to be moving it. I'm almost positive this was working pre-4.2. Any ideas as to what might be going on? Sorry for the vagueness. If you have any questions feel free to ask.
Did you try moving [super viewDidLoad] to the top of the method? Where you call a superclass's method can affect the state of inherited vars.
Good post on this: `[super viewDidLoad]` convention
It looks like you are moving so the top of popUp.view is at the bottom of self.view. And then when you are adding popUp.view to self.view you are placing it "outside" of self.view. You can verify this by newFrame.origin.y = self.view.bounds.size.height - 100; and see if it shows up.
One reason that your view doesn't show up as it did before could be that you have changed clipsToBounds. I imagine it can also be some other drawing optimization taking place and not drawing views that are out bounds and not visible.
If you want your pop up to show up below a view I think a better approach would be to either place your pop up at the bottom of your view:
newFrame.origin.y = self.view.bounds.size.height - newFrame.size.height;
or by placing the pop up view in the superview of self.view. In that case you would probably want to handle the showing in the controller of the superview.
Related
I'm a newbie at objective C programming, so please excuse me if this question has a trivial answer.
I wanted to create a UIScrollview that's larger than the screen size. In order to be able to place all the subviews appropriately inside that main view, I tried the trick suggested in this post.
In this large UIScrollView I have several subviews, such as a ToolbarView, UITextView, UIButtons and container view.
During startup I start setupView to update the frame size of the textview based on the actual screen size. I managed to do this in a separate nib file without too much trouble, but when I try this in the storyboard, a strange thing happens: the UITextView (paperlist) gets initialized and a text is set to it. However, when I try to get the frame size it results in a CGRectwith zero size.
hereunder a snippet of the code I wrote:
- (void)viewWillAppear:(BOOL)animated
{
[super viewDidLoad];
[self setupView];
// Do any additional setup after loading the view.
}
#pragma mark update the view
- (void)setupView {
// first update the paperlist height in function of the screen size of the device used
CGFloat statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
CGRect newMainFrame = self.view.frame;
CGRect newPaperlistFrame = self.paperlist.frame;
newPaperlistFrame.size.height = [UIScreen mainScreen].bounds.size.height - KEYBOARD_LOWERBORDER - self.mainToolbar.bounds.size.height - statusBarHeight;
newMainFrame.size.height = self.mainToolbar.bounds.size.height + newPaperlistFrame.size.height + self.fullKeyboardView.frame.size.height;
self.view.frame = newMainFrame;
self.paperlist.frame = newPaperlistFrame;
}
Can anybody help??
thanks in advance!
Julien
That's probably because in viewWillAppear the subviews frames are not completly initialized yet. Instead, try to call your method in this method of your viewController:
-(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[self setupView];
}
See more information here: ScrollView created in storyboard initialized with frame 0,0,0,0
I am trying to emulate the way TweetBot/NetBot animates the tabBar in after a push from the tableView of Accounts action. When the view is fully pushed, only then does the taBar animate in from the bottom. I have tried all sorts of hide/show methods and all seem to fail when it comes to the "show" part.
Does anyone have a suggestion as to how this can be done?
First of all, I presume you are not using a UITabViewController since it cannot be pushed into a UINavigationController stack, so I think you are using a standalone UITabBar embedded in a UIViewController. Is this assumption right?
Try with this code (I didn't try it).
- (void)viewDidAppear {
[super viewDidAppear];
// Calls showTabBar method after SOME_DELAY. You can also call directly [self showTabBar] if you want zero delay.
[self performSelector:#selector(showTabBar) afterDelay:SOME_DELAY];
}
- (void)showTabBar {
// Before the animation begins, your UITabBar must be outside the view controller's view frame.
CGRect tabBarFrame = CGRectMake(0,
CGRectGetHeight(self.view.bounds),
CGRectGetWidth(self.view.bounds),
CGRectGetHeight(self.tabBar.frame);
self.tabBar.frame = tabBarFrame;
// Let's start with the animation, setting a new frame for tab bar inside an animation block
[UIView animateWithDuration:ANIMATION_DURATION animations:^{
// Change origin Y. It assumes that the height of self.tabBar is right, otherwise put the height you want instead of CGRectGetHeight(self.tabBar.frame).
tabBarFrame.origin.y = CGRectGetHeight(self.view.bounds) - CGRectGetHeight(self.tabBar.frame);
self.tabBar.frame = tabBarFrame;
}];
}
I am probably doing something extremely stupid but I cannot figure out why this does not work.
I am trying to perform a simple UIView block animation but have run into trouble. I have recreated in a test project.
I have a view on a View controller, when I press the button, I create a new view and set its frame to be out of the current view (above it). I want to animate the transition so that the view currently on the screen moves downwards out of the view as the new one above it comes down to take its place.
Here is the code which is hooked up to the button,
the original view is hooked up as self.view1
- (IBAction)buttonPressed:(id)sender {
UIView *view2 = [[UIView alloc] init];
view2.backgroundColor = [UIColor blueColor];
float offScreenY = 0 - self.view1.frame.size.height;
CGRect offScreenRect = CGRectMake(0, offScreenY, self.view1.frame.size.width, self.view1.frame.size.height);
view2.frame = offScreenRect;
[self.view addSubview:view2];
float oldY = self.view1.frame.origin.y + self.view1.frame.size.height;
CGRect oldRect = CGRectMake(0, oldY, self.view1.frame.size.width, self.view1.frame.size.height);
[UIView animateWithDuration:0.5 animations:^{
self.view1.frame = oldRect;
view2.frame = CGRectMake(0, 0, self.view1.frame.size.width, self.view1.frame.size.height);
}];
}
This just animates view2 down and does not animate view 1.
If I do not add view 2 as a subview and only put view1's frame change in the animation block then view1 animates correctly.
BUT they will not work together!
Why is this?
This is a classic symptom of having autolayout turned on. If you animate frame, it works, but as soon autolayout reapplies the constraints on the view, view1 will return to its original location. By adding view2, iOS automatically reapplies autolayout constraints immediately and your view1 therefore won't move.
Bottom line, don't use autolayout and try to animate frame properties directly. Two solutions:
The easy solution is to turn off autolayout. Go to IB, select the "File inspector" and uncheck the "Use Autolayout" button:
If you want to keep autolayout on, you shouldn't be animating by changing the frame properties directly. You would animate by change the layout constraint constants. This has been answered elsewhere on S.O., but if you need guidance on that approach, let me know.
The basic idea, though, is to create an IBOutlet for your top constraint for view1 called, say, view1TopConstraint, and then in your animation block you can say
self.view1TopConstraint.constant += self.view1.frame.size.height;
[self.view layoutIfNeeded];
For this to work, though, you'd have to be careful about your other constraints on view1 (e.g., have a height constraint, have no bottom constraint or if you have one, lower its priority, etc.). This can be a hassle the first time you do it, but you'll quickly get the hang of animating by changing constraints.
But, then again, if you're using constraints, you probably shouldn't be defining view2 by its frame, but probably defining constraints for that, too.
In this case it is better for you to have a container view.
Add view1 and view2 inside this container accordingly. Container's some part will be in the screen and container's frame size will be double of the size of a view. Animate the container, so the other two views will be animated accordingly..
My UIScrollView is a ~4500px horizontal view that the user needs to scroll horizontally through to view the content.
I have set it up as follows:
- (void)viewDidLoad
{
[super viewDidLoad];
sview.frame = CGRectMake(0, 0, 568, 320);
sview.contentSize = CGSizeMake(4500, 320);
[sview setScrollEnabled:YES];
}
Yet the scroll view does nothing. Is there something obvious I missed? i've tried literally every tutorial on the web.
I got similar issue. I did following modifications and the scrollView started scrolling for me:
Select to check the 'Bounce Horizontally' property for UIScrollView
in xib.
Move the code following code to viewDidAppear instead of
viewDidLoad:
-(void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
sview.frame = CGRectMake(0, 0, 568, 320);
sview.contentSize = CGSizeMake(4500, 320);
[sview setScrollEnabled:YES];
}
I think this should help you.
I've explained it here, but there are so many answers to this problem that suggests turning off Auto Layout. That fixes the problem but that's not really the correct solution. Here's my answer:
Turning Auto Layout works, but that's not the solution. If you really need Auto Layout, then use it, if you don't need it, turn it off. But that is not the correct fix for this solution.
UIScrollView works differently with other views in Auto Layout. Here is Apple's release note on Auto Layout, I've copied the interesting bit:
Here are some notes regarding Auto Layout support for UIScrollView:
In general, Auto Layout considers the top, left, bottom, and right edges of a view to be the visible edges. That is, if you pin a view to
the left edge of its superview, you’re really pinning it to the
minimum x-value of the superview’s bounds. Changing the bounds origin
of the superview does not change the position of the view.
The UIScrollView class scrolls its content by changing the origin of its bounds. To make this work with Auto Layout, the top, left, bottom,
and right edges within a scroll view now mean the edges of its content
view.
The constraints on the subviews of the scroll view must result in a size to fill, which is then interpreted as the content size of the
scroll view. (This should not be confused with the
intrinsicContentSize method used for Auto Layout.) To size the scroll
view’s frame with Auto Layout, constraints must either be explicit
regarding the width and height of the scroll view, or the edges of the
scroll view must be tied to views outside of its subtree.
Note that you can make a subview of the scroll view appear to float (not scroll) over the other scrolling content by creating constraints
between the view and a view outside the scroll view’s subtree, such as
the scroll view’s superview.
Apple then goes on to show example of how to correctly use UIScrollView with Auto Layout.
As a general rule, one of the easiest fix is to create a constraint between the element to the bottom of the UIScrollView. So in the element that you want to be at the bottom of the UIScrollView, create this bottom space constraint:
Once again, if you do not want to use Auto Layout, then turn it off. You can then set the contentSize the usual way. But what you should understand is that this is an intended behaviour of Auto Layout.
First of all you have to add some content to UIScrollSiew as subview for scrolling,without content on UIScrollView how can you scroll?. Here is what i did,just add UIImageView to UIScrollView as subview of size same as size of UIScrollView...
In viewDidLoad method try the following code..
-(void)viewDidLoad
{
UIScrollView *scroll=[[UIScrollView alloc] init];
scroll.frame=CGRectMake(0, 0, 320, 460);
UIImageView *imageView=[[UIImageView alloc] init];
imageView.frame=CGRectMake(0, 0, 320,460);
imageView.image=[UIImage imageNamed:#"chiranjeevi.jpeg"];
scroll.contentSize = CGSizeMake(4500, 460);
[scroll setScrollEnabled:YES];
[scroll addSubview:imageView];
[self.view addSubview:scroll];
}
I tested this code it works well.I hope this code will be helpful to you..
I assume you are adding UISrollingView in your Xib file. This will work for you.
sview.delegate = self;
sview.backgroundColor=[UIColor clearColor];
[sview setCanCancelContentTouches:NO];
sview.indicatorStyle = UIScrollViewIndicatorStyleWhite;
sview.clipsToBounds = YES;
sview.scrollEnabled = YES;
sview.contentSize = CGSizeMake(320,570);
CGPoint topOffset = CGPointMake(0,0);
[sview setContentOffset:topOffset animated:YES];
Also, make sure to give IBOutlet connection in your Xib file.
I also faced the same issue.I added the scroll view in xib.I also added some subviews to this scroll view. The scroll view would stop scrolling after I added the subviews. The solution for this problem was in the xib for the view in file inspector Use Autolayout was checked. I unchecked it and the scroll view scrolled after adding the subviews.
The solution was uncheking the Use Autolayout in file inspector in xib.
I had a lot of trouble resizing a UITableView to fit between an UINavigationBar and a UITabBar. My implementation involved creating a custom frame in viewDidAppear(), and then setting the UITableView to an appropriate frame. Although this solution works well, it doesn't work perfectly- the screen has a little spasm every time the view is loaded. I figured the issue was due to the UITableViewb becoming fullscreen, as it wants to, and then me resizing it, in front of the user's eyes. However, I have no idea how else to implement what I want to: resizing the UITableView to fit into the screen properly. Here's my implementation in viewDidAppear():
- (void)viewDidAppear:(BOOL)animated{
[self.view.superview addSubview:navigationBar];
CGRect frame = self.view.frame;
frame.size.height = self.view.frame.size.height - navigationBar.frame.size.height;
frame.origin.y = self.view.frame.origin.y + 44;
self.tableView.frame = frame;
[super viewDidAppear:animated];
}
It's very hard to see the effect when recorded on video, and probably terrible in GIF form, but here's a little GIF I recorded of the flash being induced.
Here is the result if I use that same code in viewWillAppear() instead:
Thank you!
I had this problem, turned out it was an issue with auto layout on the view. In the Interface Builder, switch to the File Inspector property view and make sure 'Use Autolayout' is unchecked.
After this, you can consistently resize your UITableView in the viewWillAppear method without the glitches.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
CGRect frame = [tableView frame];
frame.size.height = 365;
self.tableView.frame = frame;
}
Why using viewDidAppear, by the time this method gets called your view is visible on screen then you will of course receive a glitch.
What you have to do is change the method from viewDidAppear to viewWillAppear.