UIPresentationController - presentation view size? - ios

I'm using a UIPresentationController, but I can't sort out how to get it showing the way I want it to.
I'm editing the frameOfPresentedViewInContainerView() function, and I need to be returning the frame (a CGRect) to display my content in.
The tutorial I followed uses CGRectInsert(self.containerView.bounds, 50, 50), which makes the window centered with the borders brought in 50px. If I return self.containerView.bounds just as itself, the view takes up the whole screen.
I'd like the overlaying view to be the width of the parent view (so, self.containerView.bounds.width), but I want the height to be the size needed to show the content of the new view without cutting anything off.
I tried a CGRect at (0,0) with width and height from self.preferredContentSize, but it's not returning sizes that work.. What can I do?
I tried frame = CGRect(x:0, y: self.containerView.bounds.height/2, width: self.containerView.bounds.width, height: self.containerView.bounds.height/2) just as a test (but that's just making the view half the size of the parent view), but when I rotate the screen, suddenly the new view is almost off screen..

Aside from frameOfPresentedViewInContainerView(), I also had to add the following to make it work.
- (void)containerViewWillLayoutSubviews
{
self.presentedView.frame = [self frameOfPresentedViewInContainerView];
}

Related

Lock UIView position relatively to UIScrollView

I am trying to create an interface that shows a floor plan with markers in fixed positions so when user zooms or scrolls the floor plan, markers stay on the same position relative to floor plan image.
So far I tried to do it with a UIScrollView that holds an UIImageView and then I tried to add some dummy subview
let view = UIView(frame: CGRect(origin: CGPoint(x: 400, y: 200), size: CGSize(width: 36, height: 36)))
view.backgroundColor = UIColor.redColor()
scrollView.addSubview(view)
but origin (in my example 400,200) is relative to screen, which means that the dummy subview shows only when you zoom enough and then slides along if you scroll around.
I can't figure out how to fix this. Maybe I should use some other UIKit classes?
Try that
create a container view of the preferred size
add the image view as a subview of this container view
add you dummy subview in the container view
from the zoom delegate method of the school view return the container view
The fact is that they need a common ancestor view

UIView appears with wrong center position

In the following function I define all the necessary characteristics of a UIView:
func OpenController() {
var gameOverView: UIView = UIView()
gameOverView.center = super.view.center
gameOverView.frame.size = CGSize(width: 200, height: 300)
gameOverView.backgroundColor = UIColor.grayColor()
self.view.addSubview(gameOverView)
}
Even though I define the center of the UIView "gameOverView" as that of the the viewcontroller it resides in, it appears with a corner in the center of the viewcontroller and not centered in the viewcontroller. I have tried various other ways of defining the position (NSLayoutConstraints, frame.x, frame.y etc.) but all have this result.
If anyone can tell me why this happens and how to center the UIView within its parent view controller I would greatly appreciate it!
Your issue here is that your center is being set before the frame. Since you are creating the view without the frame argument your frame is {0, 0}.
So you are currently centering the subview then resizing it, so this is happening:
What you need to do is resize the subview then center it, like this:
So you can just swap your centering and framing logic:
gameOverView.frame.size = CGSize(width: 200, height: 300)
gameOverView.center = super.view.center
Otherwise even easier just pass the frame when creating the view (you could even pass in the proper x, y coordinates to center it here too):
var gameOverView: UIView = UIView(frame: CGRectMake(0, 0, 200, 300))
You have to set the center of the view after setting its size. This is because before setting the size or frame of a view its frame rect is (x:0,y:0,width:0,height:0). If you then immediately set its center, then a view of size zero will get centered so its new frame rect could be (x:20,y:20,width:0,height:0) (if the parent view is 40x40). If you now change the view's size, the origin point of the view will not actually move so the new frame could be (x:20,y:20,with:5,height:5) which means the view is no longer centered.
So to center a view you have to first set its size and the its center.

Can't add a UIScrollView to a part of the view

Inside a UIViewController, I need to have the bottom half scrollable. So I added a UIScrollView and positioned it halfway down the view's height. And in the viewDidAppear method, I have put the below two code lines to make it scrollable.
self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width, self.scrollView.frame.size.height);
self.scrollView.frame = self.view.frame;
This way works if the scroll view fills the entire view, I've tested. But this method didn't work for my need. The scroll view would automatically move up and take up the entire screen. I assumed it was the second line of code which causes this.
So I removed the scroll view, added two UIViews to the view controller. To the bottom view, I added the UIScrollView. And in the viewDidAppear method, I have put the same two code lines changing the second line to refer the frame of the UIView that contains the scroll view..
self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width, self.scrollView.frame.size.height);
self.scrollView.frame = self.containerView.frame;
But it wouldn't scroll either.
Can anyone please tell me how to do this correctly?
Thank you.
Dude, you keep setting the frame of the scrollView to something completely different from what you're actually trying to achieve.
If all you want to do is setup your scroll view so that it only occupies half the space then why dont you just set the frame so that the height only covers the portion of the screen that you want it to cover; and then set the x & y coordinates so that you draw the scroll view from the right position.
Do something like this:
//Shortcut to view's frame.
CGRect viewsFrame = self.view.frame;
/**
CGRectMake takes 4 parameters: x, y, width, height
x: is set to 0 since you want the scrollview to start from the left with no margin
y: you want the y position to start half way, so we grab the view's height and divide by 2
width: you want your scrollview to span from left to right, so simply grab the view's width
height: you want your scrollview's height to be half of your screen height, so get view's height and divide by 2.
*/
CGRect frameForSV = CGRectMake(0, viewsFrame.size.height/2, viewsFrame.size.width, viewsFrame.size.height/2);
UIScrollView *myScrollView = [[UIScrollView alloc] initWithFrame:frameForSV];
[self.view addSubview:myScrollView];
Then set your content size not based on an ansolute value, its best to have it based on the size of the content that's actually inside your scrollview so that your scrollview always scrolls to cover all your content inside it.
Also, remember that your scrollview will only scroll if the contentsize is greater than the scrollview's frame
UPDATE 1 after reading your comment in this post simply comment out any code in your viewController.m file related to your scrollview since youre setting up everything in interface builder.
This is the result:

UIScrollView Increase and center content

I have the following situation: I have a UIViewController, which has a UIScrollView inside of it. The content of this scroll view, is a "canvas", where things get drawn on using CoreGraphics. The image this canvas will ultimately show is similar to a tree structure, all done programatically. My problem is: I want to be able to increase the canvas size, so that the old image is on the middle of the new allocated canvas size, and this new canvas size should then be the scroll view content, for things to get drawn around at the new allocated border and panned with.
So far this is what I have:
In the canvas class:
if (totalWidthOccupiedByChildren > totalSpaceAvailableDad) {
CGSize newSize = CGSizeMake(self.frame.size.width*1.1, self.frame.size.height*1.1);
self.frame = CGRectMake(0, 0, newSize.width, newSize.height);
[self.delegate shouldIncreaseScrollView];
}
In the ViewController class:
-(void)shouldIncreaseScrollView{
self.scrollView.contentSize = CGSizeMake(paintV.frame.size.width, paintV.frame.size.height);
}
This works "ok", and both the canvas and scroll view are increased and now allow panning, but the old image shows at the upper left corner, and I need to center it. Any idea how?
What worked for me in the end was refactoring my architechture a bit, to that I had the variables I needed. But the property which I ended up setting is scrollView.contentOffset, just for future reference :)
What you can do is, putting all the stuff inside a UIView and adding that UIView to UIScrollView. You need to ensure that UIView.center equals UIScrollView.center.
Also, you will need to adjust UIView frame size along with UIScrollView size.

How to get a subview to load properly when starting from landscape orientation

I'm building an iPad app with views that are split horizontally and animate in from the top and bottom (think of jaws sliding closed and open to appear and disappear respectively).
My problem is the layout of the custom jaws subview is broken only when the view loads in a landscape orientation. (The jaws-view container loads at the proper size, but the subsequent subviews for the top and bottom half are too tall, and going off the screen. They are the correct width though.)
I can start in portrait and then rotate and everything is arranged correctly.
I've tried setting the frame of the new view to the bounds of the original in a bunch of places (as suggested by many answers that didn't work for me, links upon request) but either haven't found the right spot, or need something more.
Do I need to do anything special to get the size to propagate? Is there a point before which I should not do animation? (I'm trying to move the top and bottom in my new view controller's viewDidLoad.)
The solution to this required 2 parts.
The first was described in this answer:
https://stackoverflow.com/a/8574519/1143123
which describes using viewWillAppear method instead of viewDidLoad (called earlier and "incorrect" values for bounds). This solved the problem of the view being layed out properly when loading that view in landscape (and propagated to subsequent rotations).
The second part was that the view could still get messed up if I started animating it and then did a rotation in the meantime. I changed my animation class to only move the center coordinate (as opposed to sliding the frame) which would have been better in the first place, but that didn't solve it. In the end I hardcoded the following in the ViewController for the class exhibiting these issues:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
// The container view should match the size of the current view
gameView.frame = self.view.bounds;
CGFloat width = self.view.bounds.size.width;
if(roundInProgress) {
gameView.jawsTop.frame = CGRectMake(0, 0, width, self.view.bounds.size.height/2);
gameView.jawsBottom.frame = CGRectMake(0, self.view.bounds.size.height/2, width, self.view.bounds.size.height/2);
} else {
// If round not in progress, game cards should be offscreen
CGFloat height = self.view.bounds.size.height/2;
gameView.jawsTop.frame = CGRectMake(0, -height, width, height);
gameView.jawsBottom.frame = CGRectMake(0, self.view.bounds.size.height, width, height);
}
}
Without seeing your code my guess is that it has to do with the "Autoresize Subviews" property of your parent view and/or the autosizing set-up for your subviews. Try changing that property in Interface Builder to see if that fixes your issue.

Resources