If I create a new single view project in XCode 5.0.2, add the iAd Framework, implementing the ADInterstitialAdDelegate in ViewController.h
#import <UIKit/UIKit.h>
#import <iAd/iAd.h>
#interface ViewController : UIViewController <ADInterstitialAdDelegate>
#end
and the delegate methods in ViewController.m
-(void)viewDidLoad
{
[super viewDidLoad];
[ self performSelector:#selector(onDelay) withObject:nil afterDelay:2 ];
}
-(void)onDelay
{
self.interstitialPresentationPolicy = ADInterstitialPresentationPolicyManual;
[ self requestInterstitialAdPresentation ];
}
-(void)interstitialAd:(ADInterstitialAd *)interstitialAd didFailWithError:(NSError *)error
{
NSLog(#"interstitialAd didFailWithError");
}
-(void)interstitialAdDidLoad:(ADInterstitialAd *)interstitialAd
{
NSLog(#"interstitialAdDidLoad");
}
none of the ADInterstitialAdDelegate methods are called. I'm also experiencing some problems using the old implementation in iOS 6 and below
interstitial = [[ADInterstitialAd alloc] init];
interstitial.delegate = self;
[ interstitial presentFromViewController:self ];
Only
-(void)interstitialAdDidLoad:(ADInterstitialAd *)interstitialAd
is called then, but no
- (void)interstitialAdDidUnload:(ADInterstitialAd *)interstitialAd
after closing the ad. Does anybody remember having the same problems or know what's going on here?
Related
I'm trying to link two different view controllers in an Xcode 6 storyboard with a NSContainerView so that they can be switched conditionally. Unfortunately this tutorial here isn't of any help since things seem to have changed since in Xcode.
So I have two different view controllers and one of them is loaded into the container view by default but I want to be able to load the second view controller into the container view programmatically. Xcode 6 only allows to create embed Segues when I drag from one to the other so that's not much of a help.
Can somebody tell me how this is achieved with Xcode 6?
First, here's a sample GitHub project of the solution: click. I wasn't sure whether you wanted to swap the views or simply push the 2nd view onto a proverbial stack, so I went with a push/pop scheme. If you want to swap the views instead, you should be able to do that fairly easily by just skipping the stack storage.
Essentially, we have our "host" NSViewController that holds a Container View (CV) inside of it. This host doesn't actually manually manage the view controller that the CV is showing at the moment. The way this is done is through, well, a sort of nested view controller that then manages all the other view controllers that you're going to show/hide/push/pop/swap/etc. (Note: you might be able to remove the layering a bit, but in iOS terms, I'm treating the 'Sub View Controller Manager' in the storyboard screenshot sort of like a UINavigationController).
We also take advantage of some custom segues/segue animators in order to be able to do more work in the storyboard.
You just have to tell the content view manager view controller to manipulate its subviews in such a way that the old views that you want to pop "back" to are retained (in this case, using an NSMutableArray) and such that the new views have the right frame or have their constraints set up properly.
Here is a screenshot of the storyboard: Each segue you see on the storyboard of a custom type (looks like this -> { } ) is of type SegueBetweenEmbedded in the sample project. Buttons that push perform a segue, and buttons labeled 'Pop' perform dismissController: on the NSViewController (so that was done in the storyboard).
Here's some code (and there's a lot of it, so I suggest looking at the sample project instead):
ViewController.h
#import <Cocoa/Cocoa.h>
#import "ContentManagerViewController.h"
#class ContentManagerViewController;
#protocol ContentManagerViewControllerHolder <NSObject>
-(ContentManagerViewController*)retreiveContentManagerController;
#end
#interface ViewController : NSViewController <ContentManagerViewControllerHolder>
#end
ViewController.m
#import "ViewController.h"
#import "ContentManagerViewController.h"
#import "BackForwardViewController.h"
#interface ViewController ()
#property ContentManagerViewController *vcController;
-(IBAction)pushViewController:(id)sender;
-(IBAction)popViewController:(id)sender;
-(IBAction)popToRootViewController:(id)sender;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
-(void)prepareForSegue:(NSStoryboardSegue *)segue sender:(id)sender {
if ([[segue destinationController] class] == [ContentManagerViewController class]) {
self.vcController = segue.destinationController;
}
}
-(ContentManagerViewController*)retreiveContentManagerController {
return self.vcController;
}
-(IBAction)pushViewController:(id)sender {
// note: this works, but then pop is broken via dismissController: since it wasn't done with a segue.
// Better way is to rig up a manual segue and execute the segue.
//BackForwardViewController *viewController = [[NSStoryboard storyboardWithName:#"Main" bundle:nil] instantiateControllerWithIdentifier:#"BackForwardStoryboardID"];
//[self.vcController push:viewController];
[self performSegueWithIdentifier:#"CustomSegueToBackForward" sender:self];
}
-(IBAction)popViewController:(id)sender {
[self.vcController pop];
}
-(IBAction)popToRootViewController:(id)sender {
[self.vcController popToRoot];
}
#end
SegueBetweenEmbedded.h
#import <Cocoa/Cocoa.h>
#interface SegueBetweenEmbedded : NSStoryboardSegue
#end
SegueBetweenEmbedded.m (sorry not sorry for the nested class)
#import "SegueBetweenEmbedded.h"
#import "ContentManagerViewController.h"
#import "ViewController.h"
#interface SegueAnimator : NSObject <NSViewControllerPresentationAnimator>
- (void)animatePresentationOfViewController:(NSViewController *)viewController fromViewController:(NSViewController *)fromViewController;
- (void)animateDismissalOfViewController:(NSViewController *)viewController fromViewController:(NSViewController *)fromViewController;
#end
#implementation SegueAnimator
- (void)animatePresentationOfViewController:(NSViewController *)viewController fromViewController:(NSViewController *)fromViewController {
NSViewController *parent = [fromViewController parentViewController];
if (parent && [parent class] == [ContentManagerViewController class]) {
ContentManagerViewController *manager = (ContentManagerViewController*)parent;
[manager push:viewController];
}
else if ([fromViewController conformsToProtocol:#protocol(ContentManagerViewControllerHolder)]) {
id<ContentManagerViewControllerHolder> holder = (id<ContentManagerViewControllerHolder>)fromViewController;
[[holder retreiveContentManagerController] push:viewController];
}
}
- (void)animateDismissalOfViewController:(NSViewController *)viewController fromViewController:(NSViewController *)fromViewController {
NSViewController *parent = [viewController parentViewController];
if ([parent class] == [ContentManagerViewController class]) {
ContentManagerViewController *manager = (ContentManagerViewController*)parent;
[manager pop];
}
}
#end
#implementation SegueBetweenEmbedded
- (void)perform {
SegueAnimator *animator = [[SegueAnimator alloc] init];
[self.sourceController presentViewController:self.destinationController
animator:(id<NSViewControllerPresentationAnimator>)animator];
}
#end
ContentManagerViewController.h
#import <Cocoa/Cocoa.h>
#interface ContentManagerViewController : NSViewController
-(void)push:(NSViewController*)viewController;
-(void)pop;
-(void)popToRoot;
#end
ContentManagerViewController.m
#import "ContentManagerViewController.h"
#import "BackForwardViewController.h"
#interface ContentManagerViewController ()
#property (weak) IBOutlet NSView *subViewControllerManager;
#property NSViewController *currentViewController;
#property NSMutableArray<NSViewController*> *viewControllerStack;
#end
#implementation ContentManagerViewController
-(instancetype)init {
self = [super init];
self.viewControllerStack = [NSMutableArray array];
return self;
}
-(instancetype)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
self.viewControllerStack = [NSMutableArray array];
return self;
}
-(instancetype)initWithNibName:(NSNibName)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
self.viewControllerStack = [NSMutableArray array];
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
}
-(void)showViewController:(NSViewController*)viewController {
[self addChildViewController:viewController];
viewController.view.frame = self.currentViewController.view.frame;
[self.view addSubview:viewController.view];
self.currentViewController = viewController;
}
-(void)removeCurrentViewControllerFromView {
[self.currentViewController.view removeFromSuperview];
[self.currentViewController removeFromParentViewController];
}
-(void)push:(NSViewController*)viewController {
[self removeCurrentViewControllerFromView];
[self.viewControllerStack addObject:viewController];
[self showViewController:viewController];
}
-(void)pop {
if (self.viewControllerStack.count > 1) {
[self removeCurrentViewControllerFromView];
[self.viewControllerStack removeLastObject];
NSViewController *viewController = [self.viewControllerStack lastObject];
[self showViewController:viewController];
}
}
-(void)popToRoot {
while (self.viewControllerStack.count > 1) {
[self pop];
}
}
-(void)prepareForSegue:(NSStoryboardSegue *)segue sender:(id)sender {
// this will be called on the initial embed to set up the first view controller
self.currentViewController = segue.destinationController;
[self.viewControllerStack addObject:segue.destinationController];
}
#end
BackForwardViewController.h
#import <Cocoa/Cocoa.h>
#interface BackForwardViewController : NSViewController
#end
BackForwardViewController.m
#import "BackForwardViewController.h"
#interface BackForwardViewController ()
#end
#implementation BackForwardViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do view setup here.
}
#end
One of the example projects in XCode 5 was named "Utility Application". It had a main view and an alternate view and set up an Info button to flip the main view to the alternate view. It used a viewcontroller delegate and a protocol definition to switch back from the flip view to the main view. In XCode 6 it is no longer there.
When I run this simple XCode 5 example app in XCode 6, I get a warning in the method below:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showAlternate"]) {
[[segue destinationViewController] setDelegate:self]; //<<<< Here is where the warning appears
}
}
The warning is: Sending 'MainViewController *const_strong' to parameter of incompatible type 'id'
What is this? A bug? The app runs fine on both simulator and iOS device. Below is the entire code. Any help will be much appreciated.
**// MainViewController.h
#import "FlipsideViewController.h"
#interface MainViewController : UIViewController <FlipsideViewControllerDelegate>
#end
// MainViewController.m
#import "MainViewController.h"
#interface MainViewController ()
#end
#implementation MainViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Flipside View
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller
{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showAlternate"]) {
[[segue destinationViewController] setDelegate:self]; //<<<< Here is where the warning appears
}
}
#end
// FlipsideViewController.h
#import <UIKit/UIKit.h>
#class FlipsideViewController;
#protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
#end
#interface FlipsideViewController : UIViewController
#property (weak, nonatomic) id <FlipsideViewControllerDelegate> delegate;
- (IBAction)done:(id)sender;
#end
// FlipsideViewController.m
#import "FlipsideViewController.h"
#interface FlipsideViewController ()
#end
#implementation FlipsideViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Actions
- (IBAction)done:(id)sender
{
[self.delegate flipsideViewControllerDidFinish:self];
}
#end**
You may have figured this out already...just wanted to post a link for for those stumbling upon this: getting a warning setting up delegate for a custom protocol
I am a student who is learning and working on an App for my school. I have just started and am doing okay. However, I am recieveing the error "Expected identifier or '(' ". I have spent a few days now reading posts and googleing, and no solution I have found is working for me.
I am trying to make a Round Rect Button on the second tab of my application to link to the school's website.
Here is the .h:
#import <UIKit/UIKit.h>
#interface SecondViewController : UIViewController {
}
- (IBAction)Website:(id)sender;
#end
and here is my .m with error commented:
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
-(IBAction)Website {
[[UIApplication sharedApplication ] openURL:[NSURL URLWithString:#"http://www.google.com"]];
}
{ **// Error is on this line[23]**
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)Website;
- (IBAction)Website:(id)sender; {
}
#end
How can I fix this little guy? Thank you very much!
Also, the .h file was formed by xCode, by simply control dragging from button, to .h and creating an action. Could this be the cause?
I think you have accidentally deleted this line:
- (void)viewDidLoad
above this line
{ **// Error is on this line[23]**
but for simplicity you could delete this:
{ **// Error is on this line[23]**
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
as you are not using viewDidLoad for anything
I am following a tutorial on here which consist of Event management with notifications and all. Now the problem is that i am getting errors in the following Codes
My .h file
#import <UIKit/UIKit.h>
#import <EventKit/EventKit.h>
#interface ViewController : UIViewController
- (IBAction) NewEvent:(id)sender;
#end
My .m file
#import "ViewController.h"
#import <EventKit/EventKit.h>
#interface ViewController ()
#end
#implementation ViewController
- (IBAction) NewEvent:(id)sender {
EKEventStore *eventDB = [[EKEventStore alloc] init];
EKEventStore *myEvent = [EKEvent eventWithEventStore:eventDB];
myEvent.title = #"New Event"; // <-- Errors are appearing hear as shown in the title.
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#end
Additional information:
i have already added the frame work but still getting error as show above in the code. The name of the code is
the property 'title' was not found on object of type "eventstore"
Thank you in advance :)
You'll want to double-check that myEvent is the right type (EKEvent * rather than EKEventStore *) and that you're actually trying to set the title on myEvent rather than eventDB. The error you posted indicates that you're setting title on an event store, instead of just an event.
I've made an application where you shake the phone to open a new view. All together three views, and when you shake the phone on the last view you go back to the first screen. This works fine when I'm creating new subclass controls view with their own .xib. But I would like to use this in a storyboard project, what do I need to change?
Thanks a lot on beforehand!
HERE IS THE CODE IN .H:
#import <UIKit/UIKit.h>
#import "FirstScreenViewController.h"
#import "SecondScreenViewController.h"
#interface ViewController : UIViewController
{
NSInteger currentScreen;
UIViewController* currentController;
}
#end
AND HERE IN THE .M:
#import "ViewController.h"
#implementation ViewController
-(void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark shake
-(BOOL)canBecomeFirstResponder
{
return true;
}
-(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
if(motion == UIEventSubtypeMotionShake)
{
if (currentController)
{
[currentController.view removeFromSuperview];
currentController=nil;
}
switch (currentScreen)
{
case 0:
currentController = [[FirstScreenViewController alloc] initWithNibName:#"FirstScreenViewController" bundle:nil];
break;
case 1:
currentController = [[SecondScreenViewController alloc] initWithNibName:#"SecondScreenViewController" bundle:nil];
}
if(currentController)
{
[currentController.view setFrame:self.view.bounds];
[self.view addSubview:currentController.view];
}
currentScreen++;
if(currentScreen >2)
currentScreen=0;
}
}
#pragma mark - View lifecycle
-(void)viewDidLoad
{
[super viewDidLoad];
currentScreen = 0;
}
-(void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
#end
You need to add all three view controllers to the storyboard, and have segues between them (including one back to the first from the third) and a shake gesture recogniser attached to each scene.
The action method for each gesture recogniser tells the view controller to performSegue: with the appropriate segue identifier.