UIView does not show properly when the uitableview is scrolled down - objective-c

I'm implementing some sort of loading screen consisting of a black coloured uiview with a spinner at it's center.
When the tableview has been scrolled down and the loading goes, the loading screen is at the top and if the tableview has been scrolled to the bottom, the loading screen disappears.
Function:
UIView *blackScreen = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
blackScreen.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
blackScreen.tag = LOADING_SCREEN_TAG;
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
spinner.center = CGPointMake(CGRectGetWidth(self.view.bounds)/2,
CGRectGetHeight(self.view.bounds)/2.3);
spinner.tag = SPINNER_TAG;
[spinner startAnimating];
[self.view addSubview:blackScreen];
[self.view addSubview:spinner];
[self.view setUserInteractionEnabled:NO];

You need to add contentOffset, I would like to refer you to this page which explains the use of it.
Here's the solution anyway, this is assuming that the variable name of your tableview is tableView and is set as a property of the class:
CGRect loadingScreenFrame = CGRectMake([[UIScreen mainScreen] bounds].origin.x + self.tableView.contentOffset.x,
[[UIScreen mainScreen] bounds].origin.y + self.tableView.contentOffset.y,
[[UIScreen mainScreen] bounds].size.width,
[[UIScreen mainScreen] bounds].size.height);
UIView *blackScreen = [[UIView alloc] initWithFrame:loadingScreenFrame];
blackScreen.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
blackScreen.tag = LOADING_SCREEN_TAG;
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
spinner.center = CGPointMake((CGRectGetWidth(self.view.bounds)/2) + self.tableView.contentOffset.x,
(CGRectGetHeight(self.view.bounds)/2.3) + self.tableView.contentOffset.y);
spinner.tag = SPINNER_TAG;
[spinner startAnimating];
[self.view addSubview:blackScreen];
[self.view addSubview:spinner];
[self.view setUserInteractionEnabled:NO];

A solution would be to not add the spinning view to the tableview but rather to its superview. It seems like you are probably using a UITableViewController which would mean that you would need to restructure your code to use a UIViewController to make this work. Adding both the UITableView and the spinner view to the view of the UIViewController would also achieve what you are looking for without having to set the center based on the content offset.

Related

iAd banner position and screen height

I'm integrating iAds for the first time. It works. What I cannot seem to do is get it at the bottom on my screen. When I do what I think is the correct math it stops showing (or rather I dont see it) but changing the position to a hardcoded value works.
// Use RootViewController manage CCEAGLView
_viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
_viewController.wantsFullScreenLayout = YES;
_viewController.view = eaglView;
// Set RootViewController to window
if ([[UIDevice currentDevice].systemVersion floatValue] < 6.0)
{
// warning: addSubView doesn't work on iOS6
[window addSubview: _viewController.view];
}
else
{
// use this method on ios6
[window setRootViewController:_viewController];
}
// iAd
adView = [[ADBannerView alloc] initWithFrame:CGRectZero];
CGRect adFrame = adView.frame;
adFrame.origin.y = adView.frame.size.height;
adView.frame = adFrame;
[_viewController.view addSubview:adView];
works but it shows like this:
When I try and change the position to the bottom based upon screen height - adView height I stop seeing it.
adFrame.origin.y = _viewController.view.frame.size.height - adView.frame.size.height;
I placed break points and it seems that this should be working based upon the values for height (1024) and adView (66)
UPDATE: I'm now trying to init specifying a rect
adView = [[ADBannerView alloc] initWithFrame:CGRectMake(0, [[UIScreen mainScreen] bounds].size.height - adView.frame.size.height, [[UIScreen mainScreen] bounds].size.width, adView.frame.size.height)];
[adView setDelegate:self];
[_viewController.view addSubview:adView];
Still not working, nothing shows anymore.
UPDATE 2: Trying this it does show, obviously not at the bottom
adView = [[ADBannerView alloc] initWithFrame:CGRectMake(0, 200, [[UIScreen mainScreen] bounds].size.width, 200)];
UPDATE 3: Trying this, it does show, obviously not at the bottom
adView = [[ADBannerView alloc] initWithFrame:CGRectMake(0, 200, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height)];
UPDATE 4: Trying this, works and it at the bottom, but I just made this up. Changing the 300 to 200 then nothing shows.
adView = [[ADBannerView alloc] initWithFrame:CGRectMake(0, [[UIScreen mainScreen] bounds].size.height - 300, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height)];
Why not use initWithFrame directly when creating banner view?
I do it as below in my app and it works fine for me
CGFloat adBannerHeight = 100.0f;
bannerView = [[ADBannerView alloc]initWithFrame:CGRectMake(0, [[UIScreen mainScreen] bounds].size.height - adBannerHeight,[[UIScreen mainScreen] bounds].size.width,adBannerHeight)];
[bannerView setDelegate:self];
[[self view] addSubview:bannerView];
Also, Please make sure you implement all necessary delegate methods

Background image too large in window/view - Part 2

This code here by sangony work for me really well but only on iPhone
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
CGRect viewFrame = CGRectMake(0, 0, 320, 568);
UIImage *background = [UIImage imageNamed:#"BG.png"];
UIImage *scaledImage = [UIImage imageWithCGImage:[background CGImage]
scale:(background.scale * 2.0)
orientation:(background.imageOrientation)];
UIImageView *backgroundView = [[[UIImageView alloc] initWithImage:scaledImage] initWithFrame:viewFrame];
[[self window] addSubview:backgroundView];
[[self window] sendSubviewToBack:backgroundView];
self.window.backgroundColor = [UIColor clearColor];
[self.window makeKeyAndVisible];
return YES;
}
Now how can I do the same idea, targeting both iPhones and iPads?
Original post can be found Here:
CGRect viewFrame = CGRectMake(0, 0, 320, 568);
I'm pretty sure you can get rid of this line of code completely:
UIImageView *backgroundView = [[[UIImageView alloc] initWithImage:scaledImage] initWithFrame:viewFrame];
Now change viewFrame to self.window.frame.
In your example, you hard-coded the frame, so no matter what the device, it will always be that size.
Although I am not a UI expert, one thing which is peculiar is:
CGRect viewFrame = CGRectMake(0, 0, 320, 568);
Why is the size of viewFrame hard coded? Shouldn't it depend on the screen you are targeting? It should be proportional to the screen size.
And also, the background image should be a different size than the size of screen, and resolution is different on iPad and iPhone.
For this, either you can use the size of the screen to pick the appropriate image, as per the screen-size, or you can scale the image.
Get the bounds of the window and set the frame
UIImageView *backgroundView = [[[UIImageView alloc] initWithImage:scaledImage] initWithFrame:self.window.bounds];

how to make a imageview do a segue

I have a bunch of imageview generated in a gridview. But now I want that each imageview can do a segue to another screen. Does anybody knows how I can do that? Here is the code of how I generated my imageview and put it into my grid.
UIImageView * myView = [[UIImageView alloc] initWithImage:myImage];
CGRect rect = myView.frame;
rect.origin.x = xCurrent;
rect.origin.y = yCurrent;
myView.frame = rect;
myView.tag = cellCounter;
[gridContainerView addSubview:myView];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
myView.userInteractionEnabled = YES;
[myView addGestureRecognizer:tap];
Please help
Kind regards
You are looking for a tapGestureRecognizer. Add one of those to your image views and make the action call your segue method.
UIImageView *img = [[UIImageView alloc] init];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(mySequeMethod:)];
img.userInteractionEnabled = YES;
[img addGestureRecognizer:tap];
A:
use a custom button instead of UIImageView, and set the image... and then segue with that button, (it looks the same)
B:
use a gesture recognizer to the view, and use a tap with one finger.

vertically aligning UINavigationItems

I have customized the UINavigationBar's height to 100px and I'd like to add buttons onto this customized bar.
All is good except the button seems to want to sit on the bottom of the nav bar no matter what. I can't get it to align to the center or the top of the nav bar.
Here is the code; first I create a navigation controller in the app delegate and add one button on the right.
// set main navigation controller
temp *tempc = [[temp alloc] initWithNibName:#"temp" bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:tempc];
UIBarButtonItem *navItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:nil action:nil];
[tempc.navigationItem setRightBarButtonItem:navItem];
[self.window addSubview:self.navigationController.view];
[self.window makeKeyAndVisible];
then I resize the navigation bar in the "temp" view controller like so:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, 100.0f);
[self.navigationController.navigationBar setFrame:frame];
[self.navigationController.navigationBar setAutoresizingMask:UIViewAutoresizingFlexibleBottomMargin];
}
I've also tried to add a custom view to the rightBarButtonItem but I can't get the added custom view to touch the top completely.
And the code for this unfortunate attempt:
// set main navigation controller
temp *tempc = [[temp alloc] initWithNibName:#"temp" bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:tempc];
UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 36.0f, 80.0f)];
[customView setBackgroundColor:[UIColor blueColor]];
UIButton *customButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[customButton setFrame:CGRectMake(0, 22.0f, 36.0f, 36.0f)];
[customButton setTitle:#"+" forState:UIControlStateNormal];
[customView addSubview:customButton];
UIBarButtonItem *customItem = [[UIBarButtonItem alloc] initWithCustomView:customView];
Does anyone know how to vertically align UIBarButtonItems on a UINavigationBar?
This will move page title and all buttons up 20 px:
[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:-20.0 forBarMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackgroundVerticalPositionAdjustment:-20.0 forBarMetrics:UIBarMetricsDefault];
The current accepted answer from alhcr (Option 1) does not work if you only have a rightBarButtonItem and no left. It is also making an assumption about the subview ordering of the UINavigationBar which is not guaranteed and could very well change in a future version of iOS. Here is a better way of customizing navigation button frames:
// UINavigationBar subclass
- (void)layoutSubviews {
[super layoutSubviews];
UINavigationItem *navigationItem = [self topItem];
for (UIView *subview in [self subviews]) {
if (subview == [[navigationItem rightBarButtonItem] customView]) {
CGRect newRightButtonRect = CGRectMake(...new rect...);
[subview setFrame:newRightButtonRect];
}
else if (subview == [[navigationItem backBarButtonItem] customView]) {
CGRect newBackButtonRect = CGRectMake(...new rect...);
[subview setFrame:newBackButtonRect];
}
}
}
Option 1:
create UINavigationBar subclass
inside this class override - (void)layoutSubviews where you will reposition UIBarButtonItems
in Interface Builder set UINavigationBar class to UINavigationBar subclass
Example:
inside subclass of UINavigationBar:
- (void)layoutSubviews {
int index = 0;
for ( UIButton *button in [self subviews] ) {
if(index == 1) {
[button setFrame:CGRectMake(5,40,60,40)]; //leftBarButtonItem
} else if(index == 2) {
[button setFrame:CGRectMake(275,40,40,40)]; //rightBarButtonItem
}
++index;
}
}
view controller:
- (void)viewDidLoad {
...
UIBarButtonItem *navItem1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:nil action:nil];
UIBarButtonItem *navItem2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:nil action:nil];
[self.navigationItem setRightBarButtonItem:navItem1];
[self.navigationItem setLeftBarButtonItem:navItem2];
CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, 100.0f);
[self.navigationController.navigationBar setFrame:frame];
...
}
Option 2 (inserting UIBarButtonItem doesn't work):
UINavigationBar *navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0,0,320,100)];
[self.view addSubview:navigationBar];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setFrame:CGRectMake(0,25,50,50)];
[navigationBar addSubview:button];
I found the solution of this problem by making adjustment in the Image Edge Insets of the custom button. I had the requirement in the app to increase the height of the navigation bar and after increasing the height makes the rightBarButtonItem and leftBarButtonItem images unpositioned problem.
Find the code below:-
UIImage *image = [[UIImage imageNamed:#"searchbar.png"];
UIButton* searchbutton = [UIButton buttonWithType:UIButtonTypeCustom];
[searchbutton addTarget:self action:#selector(searchBar:) forControlEvents:UIControlEventTouchUpInside];
searchbutton.frame = CGRectMake(0,0,22, 22);
[searchbutton setImage:image forState:UIControlStateNormal];
[searchbutton setImageEdgeInsets:UIEdgeInsetsMake(-50, 0,50, 0)];
// Make BarButton Item
UIBarButtonItem *navItem = [[UIBarButtonItem alloc] initWithCustomView:searchbutton];
self.navigationItem.rightBarButtonItem = navItem;

Creating Views without IB

It's pretty embarrassing asking this because I've been building apps for a while now. In the past I've always used Interface Builder to set up my views etc.
Here is my loadView:
- (void)loadView {
UIView *splashView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
splashView.backgroundColor = [UIColor clearColor];
UIImageView *splashImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[[NSBundle mainBundle]pathForResource:#"splash" ofType:#"jpg"]]];
splashImage.frame = [splashView bounds];
[splashView addSubview:splashImage];
self.view = splashView;
}
For some reason the imageView isn't appearing. No errors, but just no appearance. The UIView is added, but the UIImageView isn't.
Like I said, I've traditionally done this with IB so I'm not so familiar with the programatic method.
Any help appreciated.
Add splashView to self.view:
self.view = splashView;
or add your splashImage into self.view. In this case you don't need the UIView - splashView:
UIImageView *splashImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[[NSBundle mainBundle]pathForResource:#"splash" ofType:#"jpg"]]];
splashImage.frame = [splashView bounds];
[self.view addSubview:splashImage];
Try not creating a new view called splash view and just add the image view to your self.view.