How do you determine the size/frame of a custom UINavigationItem.titleView? - objective-c

After creating a custom view and assigning it to the navigationItem.titleView property it is displayed like this
with the custom view filling the space between the two buttons. Therefore, the custom view is not centered on the navigation bar. How do I determine the frame of the view in the .titleView property? I want to center some text in the navigation bar, say under the time stamp.

If you really want to get titleView's frame (in your top-level view's coordinate space), you can do this:
[self.navBar layoutIfNeeded];
CGRect titleViewFrameInTopLevelViewSpace = [self.navigationItem.titleView
convertRect:self.navigationItem.titleView.bounds
toView:self.view];
You need to do layoutIfNeeded if you have just assigned titleView, because by default the navigation bar won't lay out its subviews until the next pass through the run loop.
That said, the titleView will be centered automatically, if it fits. I think you are setting the frame (or bounds) of your custom view too large. I tested this two ways:
I set up the titleView directly in the XIB. I simply dragged a View from the Object library onto the center of the navigation bar:
It sized the view to 128x33 automatically. The resize handles let me adjust the size. It stays centered until it overlaps the Categorize button. Then it shifts left.
I set the titleView property in viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 33)];
customView.backgroundColor = [UIColor greenColor];
self.navItem.titleView = customView;
}
The result looks like this:

You could get the width of the leftBarButtonItem and the rightBarButtonItem after you've set them, and then use that to determine how to centre within the view you supply to titleView. That might do what you want?

Related

Force Subview to fill parent

I have some subviews that I place inside each of my tab bar's view controllers. Right now I'm sizing it with a pixel count but it only works on the iPhone 4 and 4s and not the iPhone 5 because of the longer screen size. I could check for the device and then size it that way but I feel like there has to be an easier way to do this.
viewController1.view.frame = CGRectMake(0, 0, 320, 460);
I colored the subview yellow so it's easier to see.
You should NOT change frame of tabbar's content view controller's view. UITabBar takes itself care of sizing the child view controller's frame properly.
If you want to add subview to content view controller (controller under some tab) and make that view to always automatically resize with the controllers main view (self.view), you can use combination of superviews frame and autoresizing.
Example code (you can do this in - (void)viewDidLoad for example):
UIView *view = [[UIView alloc] initWithFrame:self.view.bounds];
view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:view];
If you want to do this by setting frame than DO this:
[childView setFrame:childView.superview.bounds];
The master view in your view controller should already be the size of the usable space on the sceen. In general, if you want a view to be the same size as it's parent, you can use view.frame = view.superview.frame, though I doubt that would be a good idea to call on the view controller's view.

How to change the Title View of the navigation bar into some Custom View and fill the original size

I want to change the titleView of navigationBar with a regular text field. Then I want to set the textField size to fill the old "normal" titleView.
I can't seem to be able to do this in storyBoard. Dragging a text Field to the place where the navigation title View is doesn't work.
So I added stuff at
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
PO(self.navigationItem.titleView);
CGRect theFrame= self.navigationItem.titleView.frame;
self.navigationItem.titleView=self.searchBar;
//self.searchBar.frame = theFrame;
while (false);
...
It's working with one cached. That PO is a macro that print the content of the object. Turns out at viewDidAppear, self.navigationItem.titleView is null.
So while I can display the searchBar, I cannot make the searchBar "fill" it's space because I do not know the space is.
I prefer not to hard code it because you know, things may change in the future.
So what should I do?
I once saw codes where rather than setting the self.navigationItem.titleView, you would simply add subview to it. The problem with this approach even on viewDidAppear, self.navigationItem.titleView is 0.
I added these codes:
CGRect theFrame= self.navigationItem.titleView.frame;
CGRect theFrame2 = self.searchBar.frame;
CGRect theFrame3 = self.navigationController.navigationItem.titleView.frame;
And, I do not know how to nslog structure value, however, theFrame and theFrame3 are all 0
You can try this inside viewWillAppear:
UIView *customTitleView = [[UIView alloc]initWithFrame:CGRectMake((320-210)/2, 0, 210, 50)];
customTitleView.backgroundColor = [UIColor clearColor];
//create your UITextField or UILabel or other view and add as subview of customTitleView
self.navigationItem.titleView = customTitleView;

Accessory View Is Showing Up Half Off of the Cell

I cant figure out how to get my accessory view to fit into my cell. Also, When I add a subview it adds it to the right of the first subview added. I want the sub views to be added from right to left.
I have this for my accessory view
UIView *myAccessoryView = [[UIView alloc] initWithFrame:cell.accessoryView.frame];
And anytime I add a sub view I just write this
[myAccessoryView addSubview:greenCircle];
And as soon as it adds another subview it is placed to the right of the previous sub view which is even further off my cell. How do I reverse the way it adds subview? How can I format the accessory view to stay on the cell?
You are trying to init myAccessoryView with the frame of accessoryView that doesn't yet exist. It will be created after cell creation (and adding to tableView) if you specify cell.accessoryType property, or if you create and set accessoryView yourself like:
[cell setAccessoryView:myAccessoryView];
So if You do this:
UIView *myAccessoryView = [[UIView alloc] initWithFrame:cell.accessoryView.frame];
[cell setAccessoryView:myAccessoryView];
You will have accessoryView with zero size and coordinates. After the cell is set to tableView, accessoryView will get standart origin point in the right side of the cell. But it still have zero size. And all subviews You add to accessoryView will be set to that origin point.
Method "addSubview" cant change subviews frame, it just places one view to another view.
Have no ideas why new subviews are placed to the rigtht of the previous.
To put your subviews to the right place, You have to set their frames manually. For example:
UIView *greenCircle = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
[myAccessoryView addSubview:greenCircle];
Hope that helps.

Add lots of views to NSScrollView

I'm trying to add one subview (view from an NSViewController) for every element in a dictionary to a NSScrollView to get kind of a tableview, but with much more flexibility over the cells.
Is it possible to place (programmatically) e.g. 100 subviews underneath each other so that you have to scroll down the NSScrollView to get to the last element?
The short answer is yes. I have done this before, and I assure you that it will work. Let me also assure you that it is not quite as simple as it looks ;)
The way to do this is to maintain one content view, in which you add all of your custom rows as subviews programmatically. Note that you will either have to resize the contentView before adding all of the rows, or you will have to turn off autoresizing for the row views. Set the documentView of your scrollView to this custom contentView, and you should be good to go.
Yes, simply initialize the views programmatically using (i.e.)
NSView *subView = [[NSView alloc] initWithFrame:CGRectMake(10,10,100,100)];
then add to the main using addSubview: method of the main view.
Remember to manually release the subview when you've done with it (that means, when you have added it to the main view).
As example you can do something like
int height x = 10, y = 10, width = 100, height = 100;
for(int i = 0;i<100;i++) {
NSView *subView = [[NSView alloc] initWithFrame:CGRectMake(x,y + height*i,width,height)];
[scrollView addSubview:subView];
[subView release];
}

UIScrollView.size = view.size - allAdditionalBars.size (like TabBar or NavigationBar) programmatically

UIScrollView is set programmatically, please dont post answers with using .xib file.
My UIScrollView is situated in my model class, so i want the code to be able to be easly imported to another project eg. for iPad or with rotating screen.
I have a view:
self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width;, self.view.frame.size.height;)];
And my UIScrollView. I want to set it's size to cover all screen not counting all bars that my controller class will have. But i dont know how ;)
I though about subtracting self.view.frame.size.height - self.navigationController.navigationBar.frame.height and self.tabBarController.tabBar.height if each exists.
Is there any method that automatically sets UIScrollView size..?
Thank you in advance!
In your UIViewController subclass, you don't need to worry about the size of any UINavigationController or UITabBarController chrome. Those controllers will automatically resize your controller's main view to fit the appropriate content area.
If I'm creating the UIView myself in the controller's loadView, I usually just initially size it at [[UIScreen mainScreen] applicationFrame]. If I were to add a UIScrollView as a subview that would fill up the entire area of the main view (rather than just using the UIScrollView directly as the main view), I would use self.view.bounds as its frame and be sure to set autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;.