Add clickable and fixed subview to UITableViewController? - ios

I'd like to place an ADBannerView object onto my UITableView screen statically, what means that I want it to always stay above my toolbar (self.navigationController.toolbar), even when the user is scrolling the tableview. I've solved this by adding by ADBannerView as a subview to my toolbar and given it negative values for the frames origin:
[self setBannerViewSize];
[self.navigationController.toolbar addSubview:bannerView];
The only problem is: I can't click and open the iAd this way - I can see the banner but nothing happens when I tap on it.
Since I'm also using a refreshControl, the option to use a UIViewController instead of UITableViewController and add a tableView manually wouldn't work for me. Is there any other way I can get my ADBannerView statically showing in my table view controller AND still being tappable?
Thank you in advice!

Yay!! After all I succeeded in solving this (really annoying) problem by myself (and a lot of reading around)!
First, I found this really world-changing post. Basically this post handles with the topic that a UITableViewController uses self.view for its tableView property, so overriding the tableView property (or synthesizing it manually) plus giving self.view a new view (from application) and adding tableView as its subview would make it possible to reach the real superview of tableView.
But this still didn't solve my problem, although I was sure it would, because it all made sense. My bannerView appeared in the right place (and was fixed) but it still didn't do anything when clicked. But there was a second minor thing I didn't know about:
As I read in this post the superview of a subview doesn't only have to be userInteractionEnabled but also have a non-transparent backgroundColor. Because my superviews background color was set to [UIColor clearColor] it all didn't work - but setting its backGroundColor to e.g. blackColor solved the whole problem: the bannerView got finally tappable! :)
So, my code is now looking like this:
#synthesize tableView;
- (void)viewDidLoad
{
[super viewDidLoad];
if (!tableView && [self.view isKindOfClass:[UITableView class]]) {
tableView = (UITableView *)self.view;
}
self.view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
self.tableView.frame = self.view.bounds;
[self.view addSubview:self.tableView];
[self resizeTableToFitBanner];
self.view.backgroundColor = [UIColor whiteColor];
[self.view addSubview:bannerView];
// some other code
}

BannerViewController in Apple's iAdSuite sample code solves this problem very elegantly:
https://developer.apple.com/library/ios/samplecode/iAdSuite/Introduction/Intro.html

I think you should use a container view, and set things up in IB. You can add a tool bar and ADBannerView to the bottom of the view of your navigation controller's root view controller. Fill the rest of the space with a container view - this will give you an embedded view controller automatically. You should delete this one and then drag in a tableViewController and control drag from the container view to the tableViewController to hook up the embed segue.

Related

IOS Adding subview from other class programatically

i've tried to create a custom view which works like a bottom bar and it worked
Right now this function is required on multiple classes, so i try writing it into a new class and import it which likes:
//BottomBarLauncher.h
#import <UIKit/UIKit.h>
#interface bottomBarLauncher : UIViewController
-(void)launchBottomBar;
#end
And implement it as :
//BottomBarLauncher.m
-(void) launchBottomBar{
for (UIView *subView in [topView subviews]) {
[subView removeFromSuperview];
}
UIView *btnBarView = [[UIView alloc]initWithFrame:CGRectMake(0, self.view.frame.size.height - 53.3, 320, 53.3)];
btnBarView.backgroundColor = [UIColor redColor];
[self.view addSubview:btnBarView];
}
Now here's the problem, while i try implement it on a new view like follows:
//NewView.m
#import "BottomBarProtocol.h"
#interface NewView()
{
BottomBarLauncher *btnBar;
}
#end
//blahblahblah
[btnBar launchBottomBar];
and nothing happens, i think the problem was with
[self.view addSubview:btnBarView];
but i have no idea how to select the current view as target which i can add subview onto.
First a suggestion, looking at your requirements/code I think you want to create custom view. For creating a custom view, create a class which inherits from UIView rather than creating a UIViewController.
Now moving to the code, your btnBar is a UIViewController which has its own view self.view so when you call this [btnBar launchBottomBar] internally you are adding the bottom bar on self.view that is your btnBar controllers view and not on NewView controllers view. Hope you understand what I am pointing out.
Here you are missing out few calls,
btnBar.view.frame = CGRectMake(0,self.view.bounds.size.height-40,self.view.bounds.size.width,40); // Add suitable frame.
//This call will add the btnBar's view as subview onto your current view controller's view.
[self.view addSubView:btnBar.view];
This is not correct/recommended way and you can face serious challenges regarding memory leaks. To avoid those mistakes, as I suggested, create a custom UIView instead. Take a look around on how to create custom views.
Hope that helps!
You can return the UIView form launchBottomBar method and add as a subView in your current ViewController class
Make custom class and delegate and add that view in window and set its frame so that it is not visible and set its frame and slide from bottom when needed so you can use it in all view controller.
Thanks.

iOS iAd Integration Issue With UIToolBar

I am trying to add iAd into my project. The view controller that i am trying to iAd into contains a UIWebView. A UIToolBar is also added at the bottom. Above the tool bar, i have dragged a ADBannerView inside my StoryBoard. This is how it looks like:
To show the ads, this is what i have done so far: Added iAd frameWork, created an IBOutLet from AdBannerView named "banner", in viewDidLoad i assigned the delegate to self. Then i added the AdBannerViewDelegate methods and also added the following method:
- (void) viewDidLayoutSubviews {
if (self.banner.bannerLoaded) {
CGRect contentFrame = self.view.bounds;
CGRect bannerFrame = self.banner.frame;
contentFrame.size.height -= self.banner.frame.size.height;
bannerFrame.origin.y = contentFrame.size.height;
self.banner.frame = bannerFrame;
}
}
Well the iAd is properly showing with all the above i have done.
PROBLEM: The first time the view is loaded, it shows the ads properly but when i unload and reload the view again, UIToolBar disappears and is covered by the AdBannerView which is shifted below in place of UIToolBar. Can anyone points out where the problem could be and how to solve it? Thanks.
Your problem is due to setting frames in the viewDidLayoutSubviews method. When using auto layout, you shouldn't set any frames. In the storyboard, when you add the addBannerView, give it a height constraint, and spacing constraints to the to sides of the view, and a vertical spacing constraint to the tool bar (the web view should also have a vertical spacing constraint to the top of the add banner view). Delete the viewDidLayoutSubviews method, and it should work properly.
Sounds like a z-index problem to me, and if this is the case, the solution is quite simple. If you're using Interface Builder, you can use the Document Outline on the left side of your screen to drag and drop views to adjust their z-index. The bottom of the list is the highest z-index and therefore the top on screen view.
Or, if you want to make the adjustments in code, instead of using addSubview:, you can use one of the following.
[<#(UIView *)#> insertSubview:<#(UIView *)#> aboveSubview:<#(UIView *)#>];
[<#(UIView *)#> insertSubview:<#(UIView *)#> atIndex:<#(NSInteger)#>];
[<#(UIView *)#> insertSubview:<#(UIView *)#> belowSubview:<#(UIView *)#>];

Add a button to float on top of a ViewController, Path inspired

I am trying to build a button that will be floating on top of a ViewController, it should remain in the same position statically while the viewcontroller beneath it can scroll up and down.
I designed my own button class and in the viewdidload of the parent Viewcontroller I am doing this :
- (void)viewDidLoad// this is the parent viewcontroller
{
[super viewDidLoad];
customButton *floatingButton = [[UIButton alloc]initWithFrame:(self.view.frame)];
[floatingButton setLocation:CGPointMake(300, 430)];
[self.view addSubview:floatingButton];
[self.view bringSubviewToFront:floatingButton];
This is not doing it, as in when I run the button doesn't show up, only the view controller.
How can I achieve this?
I don't think that you're initializing your button properly. initWithFrame is a UIView initializer, being called by a regular UIButton. I don't see how you would get anything but an empty view here.
If you have a custom initializer for your custom button you should use
[[CustomButton alloc] myCustomInitializerWithFrame:frame];
Thanks guys, but the error was on my end, I wasn't initializing the frame properly, so the button was there but had a height and width of (0,0).

IOS: How to add one image just above Navigation Bar

I want to add a image just above the navigation bar. Here is the final result picture I want:
click me
At the beginning, I think it is quite simple:
Using UIBuilder add one UIImage and one UIView
Add navigation bar controller to UIView as its root view
The Hierarchy I thought should like this: UIViewController->UIView->NavigationBarController.(Here the UIView is one subview of the view of UIViewController)
Below is one of the code I tried, subView is the IBOutlet of one UIView builed by UIBuilder
UINavigationController *test;
test=[[UINavigationController alloc]init];
[[subView window] setRootViewController:test];
[subView.window makeKeyAndVisible];
But after trying several times,I found it is not working.
Does anyone do the same work before? If so, please give me some suggestions.
self.navigationController.navigationBar.frame = CGRectMake(0, //height of imageView//, self.view.bounds.size.width, 44.0f);
CodaFi's suggestion is almost there.
Try this:
test.view.frame = CGRectMake(0, //height of imageView//, self.window.bounds.size.width, //(total height of content... e.g. 460.0f if you leave the status bar visible)-(height of imageView)//);
There is one thing to note though... The navigation controller likes to take up all the usable space on screen so sometimes it will automatically resize its view to a rect like this, {{0.0f,0.0f},{320.0f,460.0f}} after rotating the device. I have experienced this many times on the iPad. You might have to start listening for the rotation event, and reset the frame of the navigation controller's view on every rotation to one that doesn't block your image.

UIScrollView won't show in UIView

My app is building purely programmatically on UITabBarController above a UINavigationController, which are both declared in my AppDelegate. Inside my navigationcontroller, I'm showing a UIViewController, a custom class. This custom class should show a custom UIView in a UIScrollView and a UIPageControl.
Heres my problem:
self.view seems to create an EXC_BAD_ACCESS error when I call it without declaring self.view = [[UIView alloc] init] (or similar). I was wondering if this was a problem with -(void) loadView but seems like it produces the same error in -(void)viewDidLoad. So I basically had to use self.view = scrollView to even show my scrollView, considering [self.view addSubview:scrollView] produced an error. My UIPageControl should stay on the page all the time, and actually be another part of the view than the UIScrollView. So I tried to add a container-view like this
Code:
container = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0,0,0)];
scrollView.pagingEnabled = YES;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.showsHorizontalScrollIndicator = NO;
// EDIT: ofcourse, I'm also resizing the frame with [scrollView setContentSize:] later, but this is farfetched code to add here.
[container addSubview:scrollView];
self.view = container;
Unfortunately, it seems that I don't get any result at all, and what appears is just an empty view. However, if I add a UILabel or similar, it shows:
[container addSubview:[[UILabel alloc] initWithFrame:CGRectMake(50,50,50,50)]]; // entered above or beneath the addSubview:scrollView line.
My question is: Why doesn't my scrollView appear in the UIView container?
I've noticed that some tutorials say that scrollView must have a delegate, and I agree with the logic - however I can't seem to find out how I set that delegate when I am in my CustomUIViewController-class instead of my AppDelegate.
after you change the UIScrollView size you should use:
[scrollView setNeedsDisplay:YES];
also you implement Delegates the same way you do in other classes:
.h:
#interface MyClass : NSObject <UIScrollViewDelegate>
Okay, the problem seemed to be the initialization - I didn't realize that frame and content was two different things. Seems like the frame that is initializing the view should be whatever size the view should fill, while content is the actual content of whatever should be scrolled. So when I was having problems with user interaction, it was really this.
The problem of why it didn't show in the first place was (stupid.) that the frame was initially, and never changed from, 0,0 so I really lied in my first post.
Thanks to UIScrollView and PageControl: space between views who solved my problem with user interaction.
My steps was to backtrace from self.view:
NSLog(#"%f\n%f",
((UIScrollView*) [[self.view subviews] objectAtIndex:0]).frame.size.width,
((UIScrollView*) [[self.view subviews] objectAtIndex:0]).frame.size.height);
when I realized these were 0 and 0, fixing the problem wasn't too hard :) thanks though, for your efforts Kristian.

Resources