Shared iAd on Tabbed Application - ios

New to iOS development and I have a tabbed app with 4 tabs. I have an iAd showing on one tab and I don't want to regurgetate the code on every view controller and I know this is not the correct way to implement anyway. I have looked at the Apple code here and I'm struggling to be honest.
https://developer.apple.com/library/ios/samplecode/iAdSuite/Introduction/Intro.html
I have included the BannerViewController.m and BannerViewController.h in my application but I'm not fully sure how to get it to run the ad on each view controller.
Yours confused
JKX

Just grab a reference of UIWindow in any of your ViewController Class
Go to .m of your ViewController
#import "AppDelegate.h"
#interface ViewController ()
{
//make object of AppDelegate
AppDelegate *appDelegate;
}
Now in your viewDidLoad or ViewDidAppear grab the reference of window.
appDelegate=(AppDelegate*)[UIApplication sharedApplication].delegate;
[appDelegate.window addSubview:yourBannerView];

Related

Get the presented Viewcontroller from ReactNative rootviewcontroller

In React Native project I want to access the Presented Viewcontroller from iOS npm module. I'm able to access the rootviewcontroller of the RN project using the below code
UIViewController *vc = [UIApplication sharedApplication].delegate.window.rootViewController;
But I want the current VC that is presented on top of RootVC so that I should be able to present native(iOS) UINavigationController on top of it.
Note:[UIApplication sharedApplication].delegate.window.rootViewController.presentedViewController returns nill.
I know this was asked a long time ago, but I was running into the same problem today ([UIApplication sharedApplication].delegate.window.rootViewController.presentedViewController returns nil) and couldn't find the solution for a while, so I'll leave this here for anyone still looking.
There's a function in the React Native source code that allows you to determine the presented view controller. It seems like they use this for their ActionSheetIOS module (see this line). To use this in your own native module, add the following:
// Put this near the top of the file
#import <React/RCTUtils.h>
...
// Put this where you need access to the presented view controller
UIViewController *presentedViewController = RCTPresentedViewController();

PubNub and Multiple View Controllers

I'm making an app that will use PubNub for a group chat part of the app. I turned on Playback on my app and I completed the tutorial for setting up the code. I'm confused though, because all the code was in the AppDelegate, and I have my chat view controller as part of my storyboard. My question is, what setup code do I have to do in my view controller so I can get all the past 100 messages using the historyForChannel:start:end:limit:withCompletion: method. Would I have to make a new instance of the PubNub client? That doesn't make sense since the user will be switching view controllers and It should be stored in a long life property.
What setup code do I have to do in my view controllers to get the past messages? (To be loaded into a very elaborate tableview setup)
So I figured out a working solution. First, you have to make the PubNub client property public by defining it in the AppDelegate.h file, not the .m implementation.
// AppDelegate.h
#import <UIKit/UIKit.h>
#import <PubNub/PubNub.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate, PNObjectEventListener>
#property (strong, nonatomic) UIWindow *window;
// Stores reference on PubNub client to make sure what it won't be released.
#property (nonatomic) PubNub *pnClient;
#end
And don't forget to delete from the AppDelegate.m
#import "AppDelegate.h"
#interface AppDelegate ()
/*
// Stores reference on PubNub client to make sure what it won't be released.
#property (nonatomic) PubNub *pnClient;
*/ // Delete from here
#end
#implementation AppDelegate
If you want to do notifications and such, keep the AppDelegate as a listener to the [self.pnClient] property. If not, just delete <PNObjectEventListener> from the AppDelegate.h and [self.pnClient addListener:self]; from your AppDelegate.m. If you prefer to keep it, just don't delete that stuff.
Now, #import your AppDelegate in your ChatViewController.h or the .m of you prefer. Then, make your .h conform to the <PNObjectEventListener> delegate. The, before you forget, add another client in your .h or .m to store the property of your PubNub client in your AppDelegate. :
// Stores reference on PubNub client to make sure what it won't be released.
#property (nonatomic) PubNub *pnClient;
Next, in your viewDidLoad method, add:
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
self.pnClient = appDelegate.pnClient;
[self.pnClient addListener:self];
This code first grabs the AppDelegate of your app, (so there are no shared instance or singleton things involved). Then, It sets the pnClient of your app delegate to your "temporary" client in your view controller. (See why we moved the AppDelegate's client to the .h?) And lastly, it adds self as a listener, so you can do stuff in your view controller.
Thats all there is to it!
I would suggest using your chat controller to populate a UITableView or something else, and the AppDelegate for handling notifications.

UIViewController Is Not Working

This behavior is very odd. Every time I create a new project in Xcode 5.0.2 I cannot get it to work fully. Once the Single View Application template (or another) is created - everything seems OK: I have my delegate, storyboards and ViewController. They all run successfully and I can even see newly added UIView's in my Simulator.
Her is my generic code for ViewController:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController{
UIView *container;
}
#property (nonatomic,retain) IBOutlet UIView *container;
#end
#import "ViewController.h"
#interface ViewController (){}
#end
#implementation ViewController
#synthesize container;
- (void)viewDidLoad{
[super viewDidLoad];
NSLog(#"App loaded");
}
- (void)didReceiveMemoryWarning{
[super didReceiveMemoryWarning];
}
#end
But once I add properties to this controller class and synthesize them, the screen turns black during app running and no views or whatever was added before is ever seen anymore. Just a blank black color screen.
Where is the problem? Please note:
I checked Info*.plist and it points to Storyboard correctly
In delegate my didFinishLaunchingWithOptions returns YES
ViewController has a Initial View Controller checked and is the only one in the storyboard
viewDidLoad prints NSLog message successfully even though nothing is shown
What to check?
Here is a link to the project
A view controller is just that, a controller. The UIViewController's view property is what is visible on the screen (assuming you added it to the screen at some point, storyboard, programatic, xib, etc...)
Check the UIViewcontroller.view.superview. You should be able to get close to what you want.
The view controller properties thing is a complete red herring.
You're using a storyboard for your app, which has all of the relevant details in it. Then, in your app delegate, you've added a load of code to load in a new instance of the view controller and set it as your app's root view controller.
You don't need to do this if you have a storyboard. Just return YES from applicationDidFinishLaunching.. (which was originally the case, since you included the git history in the download!). The initial view controller from your storyboard will already be loaded up. What you've done is to basically ignore the storyboard.

Getting Started with MMDrawerController

I'm trying to get MMDrawerController to work, and I'm having trouble.
Here's is how much app is structured in my storyboard:
Here's how I'm attempting to initialize it from within my root view controller:
//LCViewController.m
#import "LCViewController.h"
#import "MMDrawerController.h"
#interface LCViewController ()
#property (nonatomic,strong) MMDrawerController * drawerController;
#end
#implementation LCViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.drawerController = [[MMDrawerController alloc]
initWithCenterViewController:[self.storyboard instantiateViewControllerWithIdentifier:#"centerNav"]
leftDrawerViewController:[self.storyboard instantiateViewControllerWithIdentifier:#"menu"]
rightDrawerViewController:nil];
}
...
#end
When I build my app, all I see is my root view controller. Is there something else I'm supposed to do to implement the drawer functionality?
I created a demo project to show how I'm trying to set up my app. You can download the Xcode workspace here. Thanks in advance for your help!
I'm using Xcode 5 and iOS 7
EDIT: Sorry I initially misunderstood your app structure. The MMDrawerController should be the root view controller of your application. You should move this code from viewDidLoad to application:didFinishLaunchingWithOptions:. Add an MMDrawerController property to your app delegate, init the drawer controller with your appropriate views, and set the drawer controller to the rootViewController on your UIWindow. Do this along with setting the gesture modes as I described below and the drawer should work.
To get the basic open/closing gestures, set this properties on your drawer controller:
self.drawerController.openDrawerGestureModeMask = MMOpenDrawerGestureModeAll;
self.drawerController.closeDrawerGestureModeMask = MMCloseDrawerGestureModeAll;
These properties default to MMOpenDrawerGestureModeNone which is why you couldn't make anything slide. You can have a look at the MMOpenDrawerGestureMode and MMCloseDrawerGestureMode bitmasks to get finer grained settings if you desire.
You can also create UI controls that toggle the drawer by calling toggleDrawerSide:
animated:
completion:.

Programmatically Selecting a TabBarController View?

In order to get my custom menu up and running, I've ended up using a UITabBarController and need to change the view displayed programmatically, vs the standard tabbed menu on screen.
Everything is working as expected except on thing. I am attempting to use:
[self setSelectedIndex:index];
This code is inside my UITabBarController subclass in a custom delegate method. (This is so I can programmatically adjust the view when interacting with my menu). However, while this code is called, it doesn't do anything?
Does it HAVE to be called from one of the tabbed views? I was hoping to run it from inside the TabBarController to avoid repeating the code in each tabbed sub controller.
UPDATE:
Just found that using [self setSelectedIndex:index]; works fine in viewDidLoad. But when it is called inside the delegate method, it doesn't change view. It is using the right index number and getting called, but not doing anything from that method.
Also, it seems the tab controller is a different object when I log self in viewDidLoad vs my delegate method. So why would I be loosing the reference to the original controller?
It's just a UITabBarController in a container in another view controller.
Delegate Code:
#Interface
#protocol SLMenuDelegate <NSObject>
#required -(void)menuDidChangeViewToIndex:(NSInteger)index;
#end
#property (nonatomic, assign) id<SLMenuDelegate>menuDelegate;
#Implementation
#synthesize menuDelegate;
self.menuDelegate = [self.storyboard instantiateViewControllerWithIdentifier:#"TabBarViewController"];
[menuDelegate menuDidChangeViewToIndex:[self.menuItemButtons indexOfObject:sender]];
UITabBarController
-(void)menuDidChangeViewToIndex:(NSInteger)index
{
[self setSelectedIndex:index];
}
Setting breakpoints and running NSLogs and there is no question that the method gets called and all code runs.
Try using delayed performance:
dispatch_async(dispatch_get_main_queue(), ^{
[self setSelectedIndex:index];
});
I didn't manage to find a solution to the exact issue, but I found an equally good way of resolving my issue simply.
I stopped using a delegate to send my button tap message and change the view. Instead I did the following:
SLTabBarViewController *tabBar = [self.childViewControllers objectAtIndex:0];
[tabBar setSelectedIndex:[self.menuItemButtons indexOfObject:sender]];
This gets the embedded tab bar controller and I simply directly change the view from the original view controller from which the button tap comes from.
It may not be an intelligent solution, but its a simple and functional one which doesn't create any problems.

Resources