UINavigationBar custom title being hidden by background - cocoa-touch

I am adding a custom UIImageView to my UINavigationBar using this code:
UIImageView *background = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)] autorelease];
[background setImage:[UIImage imageNamed:#"nav_background.png"]];
[background setTag:kTagForReference];
[self.navigationController.navigationBar insertSubview:background atIndex:0];
I then add a custom title using this code:
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 400, 44)];
...
[self.navigationItem setTitleView:label];
[label release];
But on some of my pushed views the title is being hidden (or isn't visible). I can't seem to push more than two views onto the stack without the title disappearing.
I've tried to force my UIImageView background to the back of the bar but that still doesn't help. I've printed the subviews of the UINavigationBar and I can see that the UILabel is there, I just can't see it!
Any help would be greatly appreciated.

If you can run the dumpWindows() function, the output would show the view hierarchy so you can see what view is covering it up.

You most likely want to use a UIToolBar instead of a NavigationBar. Then you can add the subviews to the UIToolbar.
Bring the UILabel to the front most view.
[self.view bringSubviewToFront: label];

Related

How to move scrollView down 44x to make room for NavBar

I am using the following code to create my scrollview. I would like to move the scrollView down 44px to make room for my nav bar.
scroll = [[UIScrollView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
scroll.backgroundColor = [UIColor clearColor];
scroll.delegate = self;
image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Menu.png"]];
scroll.contentSize = image.frame.size;
[scroll addSubview:image];
scroll.minimumZoomScale = scroll.frame.size.width / image.frame.size.width;
scroll.maximumZoomScale = 2.0;
[scroll setZoomScale:scroll.minimumZoomScale];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
[doubleTap setNumberOfTapsRequired:2];
[scroll addGestureRecognizer:doubleTap];
self.view = scroll;
any help is appreciated.
Your code is correct, to manually create a frame do:
scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0,44,320,480)];
:)
This is for iPod and iphone View but this will let the scroll start at 44px
Cant you just add a scroll view in in interface builder as an outlet, place it underneath your nav bar.
Declare scroll view in .h
in .m under ViewDidLoad
[scroll setScrollEnabled:YES];
[scroll setContentSize: CGSizeMake(320, 1000)]; ////or whatever size you want here
You probably want to init it with a different frame... but it depends on where/how this nav bar is being created. If you have a view controller, and these are all subviews of the view controller's view, then you should be creating the objects in viewDidLoad, then just create the nav bar first, using self.view.bounds to obtain the initialization width. I assume you'll want to put UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin as the autoResizingMask here. Then if the scrollview is the rest of the view below the nav bar, you can create the frame for it using
CGRect scrollFrame = CGRectInset(self.view.bounds, 0, navbar.bounds.size.height)
Put an autoresizingMask of UIViewAutoresizingFlexibleWidth | UIViewAutoResizingFlexibleHeight on the scrollview.
If you are creating the views in a different place/way, then some of that might need modification. I was assuming your view is a nav bar at the top, x pixels tall (44 in this case but it doesn't and shouldn't matter in the context of setting the scrollview frame). and then a scrollview that fills the rest of the view.

UIGestureRecognizer's sender view not working properly

According to this question, the UIGestureRecognizer has a view property which refers to the view the gesture is attached to. I used this in my code like this:
//Code for the 1st UIScrollView
UIImageView *bookCover = [[UIImageView alloc]initWithFrame:CGRectMake(50, 100, 145, 420)];
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc]initWithTarget:self
action:#selector(downloadBookTapped:)];
[bookCover addGestureRecognizer:singleTap];
[bookCover release];
[singleTap release];
//Code for the second UIScrollView
UIImageView *fileCover = [[UIImageView alloc]initWithFrame:CGRectMake(50, 100, 145, 420)];
UITapGestureRecognizer *singleFileTap = [[UITapGestureRecognizer alloc]initWithTarget:self
action:#selector(downloadFileTapped:)];
[fileCover addGestureRecognizer:singleFileTap];
[fileCover release];
[singleFileTap release];
And here is where I user the view property:
- (void)downloadBookTapped:(UITapGestureRecognizer *)sender
{
UIImageView *imgView = (UIImageView *)sender.view;
CGRect rect = [imgView frame];
UIImageView *images = [[UIImageView alloc]initWithFrame:rect];
//rest of code here...
}
- (void)downloadFileTapped:(UITapGestureRecognizer *)sender
{
UIImageView *imgView = (UIImageView *)sender.view;
CGRect rect = [imgView frame];
UIImageView *images = [[UIImageView alloc]initWithFrame:rect];
//rest of code here...
}
The problem here is that I have two scrollView and each scrollview holds multiple books. When I select a book at the 1st scrollView, the images is displayed correctly. But when I select a book inside the 2nd scrollView, the images is displayed incorrectly. Can anyone explain why this happens? Thanks.
---ADDITIONAL INFO---
The two scrollViews have the same width and height. The difference, of course, is there placement. The first scrollView is placed at (0, 0), while the second is at (0, 350). You can imagine the two as "shelves", the first one being the top shelf and the second one being the bottom shelf.
To specify the problem, say that I selected a book inside the second scrollView. The images will then be displayed as if I selected a book in the 1st scrollView. Meaning, the images is displayed in the 1st scrollView instead of the second scrollView.
Because the gestureRecognizer is bound to the first UIImageView and not the second.
[bookCover addGestureRecognizer:singleTap];
Do this for your other UIImageView and you will get the results you want.
I know now what I did wrong! Instead of adding the images as the subview of the scrollViews, I did this:
[self.view addSubView:images];
That's why It keeps appearing on the top side. It should be like this:
[scrollBook addSubview:images];
[scrollFile addSubView:files];

set background image dimensions IOS

I have an image bigger then a normal iPhone screen that I want to set as my background image but when I load the simulator I just see part of the image. Here is how I assigned the image:
UIImage *background = [UIImage imageNamed:#"background.png"];
[self.view setBackgroundColor:[UIColor colorWithPatternImage:background]];
how can I set the background image to something like self.view.bounds? If I was to use a UIImageView how do I ensure that it is in the background!!!
Make a UIImageView, give the UIImage to the UIImageView and add the UIImageView as a child to the view. Like so:
UIImageView *backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"name.png"]];
[backgroundView setFrame:CGRectMake(0, 0, 320, 480)];
[self.view insertSubView:backgroundView atIndex:0];
[backgroundView release];
Set uiimageview frame - this is limitations for display.
Use
background.frame = CGRectMake (0,0, 320, 480); // as example - full screen,
also like in post above add addSubview and release code.
If you used frame - coordinates calculate from your superview - in that case - from self.view (simulator display). If you used bounds, coordinates calculate relatively to yours uiimageview (not self.view)

UIView size is not as expected to be

I can't figure out why that view takes the entire screen.
In AppDelegate file
...
self.viewController = [[[ViewController alloc]init]autorelease];
[self.window setRootViewController:self.viewController];
self.window.backgroundColor = [UIColor whiteColor];
..
In ViewController.m
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(30, 30, 30, 30)];
[view setBackgroundColor:[UIColor greenColor]];
self.view = view;
When I run the app the screen is entirely green instead of having just a square in green.
What is wrong here ?
The erroneous line is here:
self.view = view;
When you set a view of a UIViewController that is the root controller, it is guaranteed to fill the screen. Instead, add it as a subview:
[self.view addSubview:view];
And you should be fine.
The view controller automatically manages the size of its root view (self.view), so even if you initialize it with a smaller size it will later get resized to fill the screen. This resizing conveniently also happens when the interface orientation changes (see the answer this question).
As suggested by Richard's answer, you can add your green view as a subview to the controller's root view. The crash you get is probably because the root view does not exist yet when you try to access it. Try the following:
- (void) loadView
{
[super loadView]; // creates the root view
UIView* subView = [[UIView alloc] initWithFrame:CGRectMake(30, 30, 30, 30)];
[subView setBackgroundColor:[UIColor greenColor]];
// because you don't set any autoresizingMask, subView will stay the same size
[self.view addSubview:subView];
}

UITableViewCell custom selectedBackgroundView background is transparent

I have the following code that creates a UIView that I assign to my UITableViewCell's selectedBackgroundView property. Everything works as expected, with the exception of the subview's background, which is transparent.
I use the same code to create a custom view that I assign to backgroundView, and that works fine.
What is causing that subview to be transparent for selectedBackgroundView, and how can I avoid that?
- (UIView*) makeSelectedBackgroundView
{
// dimensions only for relative layout
CGRect containerFrame = CGRectMake(0, 0, 320, 40);
UIView* containerView = [[UIView alloc] initWithFrame:containerFrame];
containerView.autoresizesSubviews = YES;
// dimensions only for relative layout
CGRect subframe = CGRectMake(5, 5, 310, 30);
UIView* subview = [[UIView alloc] initWithFrame:subframe];
subview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
subview.backgroundColor = [UIColor redColor];
subview.layer.cornerRadius = 5;
subview.layer.borderWidth = 2;
subview.layer.borderColor = [UIColor greenColor].CGColor;
[containerView addSubview:subview];
return containerView;
}
As we can see from name of ivar selectedBackgroundView, this background shown by cell when it was selected.
I've to reload few methods (– setSelected:animated: and – setHighlighted:animated:) of UITableViewCell subclass to reset background color of subviews back to their values. Look's like UIKit do some magic in this template methods (iterating over all UIView subclasses and set their background to clearColor)
This code might be helpful for you:
UIImageView *cellImageView = [[UIImageView alloc]
initWithFrame:CGRectMake(0,
0,
cell.frame.size.width,
cell.frame.size.height
)];
cellImageView.contentMode = UIViewContentModeScaleAspectFit;
// normal background view
[cellImageView setImage:[UIImage imageNamed:#"*<ImageName>*"]];
[cell addSubview:cellImageView];
[cell sendSubviewToBack:cellImageView];
[cellImageView release], cellImageView = nil;
Here cell is an object of custom UITableViewCell.
Also you can set backgroundColor property.
I would try to set the alpha for both containerView and subView to 1.0
[containerView setAlpha:1.0];
...
[subview setAlpha:1.0];
this should make your controls totally opaque.
You could also create some images for the background and use that images in state of creating 2 views. Let's say you create 2 image (normalBackground.png and selectedBackground.png) and then set this images as cell background. Here is a nice tutorial.
Try setOpaque:YES on your views.
In the end, I ended up subclassing UITableViewCell which contained a custom view object, and that worked.