Position a UIView at the middle of a UITableView with CGRectZero frame - iphone

I have a UITableViewController view a UITableView that I alloc/init with a frame of CGRectZero :
self.tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
I want to add a view at the middle of the tableView (a loading view with a UIActivityIndicatorView and a UILabel), but I don't know how to position it, since I don't know the tableView frame.
x = (self.tableview.frame.size.width - loadingView.frame.size.width) / 2.0;
y = (self.tableview.frame.size.height - loadingView.frame.size.height) / 2.0;
[loadingView setCenter:CGPointMake(x, y)];
I did init my tableView with CGRectZero frame so it can take the whole place available on screen (which it did), but I thought its frame would update or something.
Any ideas ? Thanks !

I managed to estimate to frame programatically. I didn't mentionned that my tableView was between a navigationBar and a tabBar, so here is the code for this case :
CGFloat x = self.navigationController.view.frame.size.width;
CGFloat y = self.navigationController.view.frame.size.height -
self.tabBarController.tabBar.frame.size.height;
self.tableView = [[UITableViewController alloc] initWithFrame:CGRectMake(0.0, 0.0, x, y)];
And the code posted above for the positionning of the loadingView works like a charm !
I'm open ton better solutions, of course

You could give your LoadingView a reference to the view it is to appear over. Then when it is about to be shown, it can check the frame of the view it is representing to center and match that view and add itself as a subview of the TableView's superview:
- (void)show
{
self.center = targetView.center;
[[targetView superview] addSubview:self];
}
Another option is to have the LoadingView use KVO to monitor the UITableView's frame and adjust it's own frame accordingly.

If your View Controller is a UITableViewController then the frame of the table view is the same as the frame of the UIViewController.
Why don't you put it in the center of the UIViewController's view?
Assuming self is the UITableViewController:
loadingView.center = self.view.center;

Related

Objective c - proper way to set subview frame so it will fill the screen

I have a viewController inside of a navigationController, the view controller has a tableview.
In viewDidLoad I set the tableview
- (void)viewDidLoad
{
[super viewDidLoad];
// init tableView
CGRect tableFrame = self.view.bounds;
_tableView = [[UITableView alloc] initWithFrame:tableFrame style:UITableViewStylePlain];
_tableView.delegate = self;
_tableView.dataSource = self;
[self.view addSubview:_tableView];
}
The problem with this code is that the table view frame is not correct - the height is 460 and I need it to be 416.
[The iPhone screen height is 480, minus the status bar (20) minus the navigation bar (44) = 416]
So what is the proper way to set the table view so it will fill the screen?
I can think of two ways:
set its frame to = (0, 0, 320, 416)
use: [_tableView setAutoresizingMask:(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth)];
Don't use magic numbers. Use the resizing flags correctly.
So yes, your 2. approach is correct.
1) Use the superviews bounds._tableView.frame = self.view.bounds;;
2) Set autoresizing flags [_tableView setAutoresizingMask: UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];
(you did all of this already :)
Number 1 is absolutely the wrong way to do it... what happens if the screen size changes in a future OS / device?
I'm curious why you're not doing this using a nib file, and saving yourself the trouble, but if you must do it in code, set the auto-resizing mask per your option 2.

How to create a table in a view ( I dont want the table to cover up my entire screen)

Is there any way out .., that I can create a UITableView in a view such that it doesn cover up entire the screen...
For example :
I want the first half of the screen to be a UITextView and the next half portion of my screen to be
a UITableView..
Thanks in advance
CGRect cgRct = CGRectMake(0, 50, 320, 250);
UITableView *tableView1 = [[UITableView alloc] initWithFrame:cgRct style:UITableViewStylePlain];
//tableView.editing = YES;
tableView1.dataSource = self;
tableView1.delegate = self;
tableView1.backgroundColor=[UIColor clearColor];
[self.view addSubview:tableView1];
You are probably creating a UITableViewController for your tableView and then realizing that you can't change the size of the tableView. Am I right? If that is the case then don't create a UITableViewController, just create a normal UIViewController and than add your tableView using Interface Builder or the code which other people posted here.
In Interface Builder (if you are using it), just drag-drop a UITableView to your UIView and adjust its width, height and y position in the Inspector.
If you are programmatically creating the view, change the frame of the UITableView
CGRect tablefrm = [tableViewObject frame];
tablefrm.origin.y = 240.0f //new origin
tablefrm.size.height = 240.0f; //new height
[tableViewObject setFrame:tablefrm]; //assuming already added the tableview to the view.

Need UIView to autoresize

I have made a custom UIView which is shown when the user hits a button in the navigationbar. I make my view's in code. In my loadview I set the autoresizing masks and the view loads correct on screen. However the UIView which is shown when the user taps the button does not resize even when I have set the autoresizing masks.
UIView *blackView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 416.0)];
blackView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
Do I need to use self.view.frame.size.width and self.view.frame.size.height instead? And if I do why? Does not resizing masks work outside of loadView?
Thank you for your time:)
the autoresizingMask affects how a view will behave when its superviews frame changes. if all you are doing is showing theblackViewwhen you tap a button, thenblackView` will have whatever frame you initially set for it.
If this isn't enough info, please post some more code around how you are configuring and displaying blackView and it's superview and explain more about what situations you are expecting blackView to resize in. Rotation is one of them, if that's what you're concerned with.
First things first, I hope you've done this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
Let's say the view that needs resizing is: view2
The view that has view2 as a subview is: view1
While creating view1 you would declare it as:
view1 = [[UIView alloc] init];
[view1 setNeedsLayout];
Now in view1's .m file you need to overload the layoutSubviews method as shown:
- (void)layoutSubviews
{
CGRect frame = view2.frame;
// apply changes to frame
view2.frame = frame;
}
In case view1 is a view controller's view, you need to do that same thing as above in the willRotate method as shown
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
CGRect frame = view2.frame;
// apply changes to frame
view2.frame = frame;
}
This is a tried and tested method that I use to handle orientation changes.

Dynamically changing position of a UIView

Here's my setup. I have a viewcontroller that I'm creating and adding as a subview. The viewcontroller presents some options that a user can chose from. The viewcontroller is being pushed in response to a "long press" gesture. Within the viewcontroller, I added a child UIView to group some other controls together so I can move them around the screen as a unit and, when they are displayed, center them on the location of the long press. Here is the code that instantiates the view controller, changes its location, and adds it as a subview:
UserOptions *opts = [[UserOptions alloc] initWithNibName:#"UserOptions" bundle:nil];
[opts recenterOptions:location];
[self.view addSubview:opts.view];
That bit of code does create and push the viewcontroller, but the call to recenterOptions doesn't do anything. Here is that method:
- (void) recenterOptions:(CGPoint)location {
CGRect oldFrame = self.optionsView.frame;
CGFloat newX = location.x; // + oldFrame.size.width / 2.0;
CGFloat newY = location.y; // + oldFrame.size.height / 2.0;
CGRect newFrame = CGRectMake(newX, newY, oldFrame.size.width, oldFrame.size.height);
self.optionsView.frame = newFrame;
}
Note that self.optionsView is the child UIView that I added to the viewcontroller's nib.
Does anyone know why I'm unable to change the location of the UIView?
Regards,
Eric
A couple things. First, try adding the view to the view hierarchy before calling -recenterOptions:
UserOptions *opts = [[UserOptions alloc] initWithNibName:#"UserOptions"
bundle:nil];
[self.view addSubview:opts.view];
[opts recenterOptions:location];
Next, just set the center of the view instead of trying to change its frame:
- (void) recenterOptions:(CGPoint)location {
[[self optionsView] setCenter:location];
}
Are you verifying that your optionsView is valid (non-nil)?
I agree with Rob, btw. You need to change your title to match your question.
Views are loaded lazily. Until you call self.view, the view is not loaded and optionsView is nil, hence self.optionsView.frame = newFrame does nothing.

UIButtons at the bottom of a UIScrollView are not receiving touches

I am writing an iPhone app with a tab bar and navigation bar. At a certain point, I am pushing an instance of my DetailsViewController class onto the navigation controller stack to show it.
This controller creates its view hierarchy in code: the controller's view property is set to a UIScrollView, which contains a plain UIView (let's call it "contentView") sized to hold all the content to be shown. At the bottom of this contentView, I have four UIButtons.
Now when I run the app (in the simulator at present), and scroll to the bottom of the view, the top two buttons respond to touches; the third responds to touches only in the top portion of it, and the lower button doesn't respond to touches at all. By clicking in various parts of the third button, it appears that the lower 93 pixels of the scroll view is not passing touch events through to its subviews.
93 is suspicious: it's also the combined height of the tab bar (49 pixels) and navigation bar (44 pixels). Yet the navigation bar and tab bar are outside the scroll view. Any suggestions why this might be happening?
Here's the code in question:
- (void)loadView
{
CGRect frame = [[UIScreen mainScreen] applicationFrame];
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:frame];
scrollView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
scrollView.delegate = self;
self.view = scrollView;
UIView *contentView = [[UIView alloc] initWithFrame:scrollView.bounds];
contentView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
[scrollView addSubview:contentView];
CGSize viewSize = contentView.bounds.size;
CGSize size;
CGFloat y = 0;
/* Snip creating various labels and image views */
/* Actions view creates and lays out the four buttons; its sizeThatFits:
** method returns the frame size to contain the buttons */
actionsView = [[PropertyDetailActionsView alloc] initWithFrame:CGRectZero];
actionsView.autoresizingMask = (UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth);
actionsView.delegate = self;
size = [actionsView sizeThatFits:viewSize];
actionsView.frame = CGRectMake(0, y, size.width, size.height);
[contentView addSubview:actionsView];
y += size.height;
[contentView setFrame:CGRectMake(0, 0, viewSize.width, y)];
scrollView.contentSize = contentView.frame.size;
[contentView release];
[scrollView release];
}
As I suggested on Twitter yesterday, it may have something to do with the flexible bottom margin set to the actionsView.
That suggestion did not resolve the problem, yet it lead to the right direction. By removing the flexible height of the contentView the problem has been fixed.
So if anyone out there is having similar problems, try to play with your autoresizingMasks.
also make sure all your content views are the height that covers the bottom button.
I make each view a different color to see them.