I have 2 viewcontroller. In the first viewcontroller, there is the introduction and logo of the game and in the second viewcontroller it loads the skscene. And I travel from my first viewcontroller to second viewcontroller with a button click. But it becones error. My code is in the second viewcontroller is:
#interface MPAPViewSceneController()
#property (nonatomic, retain) MPAPMyScene *targetScene;
#property SKView *spriteView;
#end
- (void)viewDidLoad
{
[super viewDidLoad];
_spriteView = (SKView *)self.view;
_spriteView.showsFPS = YES;
_spriteView.showsNodeCount = YES;
_spriteView.showsDrawCount = YES;
}
-(void)viewWillAppear:(BOOL)animated {
self.targetScene = [[MPAPMyScene alloc] initWithSize:CGSizeMake(768.0f, 1024.0f)];
[_spriteView presentScene:self.targetScene];
}
-(void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:YES];
self.targetScene = nil;
}
And in the scene I have written the code given below:
#interface MPAPMyScene()
#property (nonatomic) BOOL contentCreated;
#end
#implementation MPAPMyScene
-(void)didMoveToView:(SKView *)view {
if (self.contentCreated == NO) {
[self createSceneContents];
self.contentCreated = YES;
}
}
-(void)willMoveFromView:(SKView *)view {
[self removeAllChildren];
}
-(void)createSceneContents {
self.backgroundColor = [UIColor blueColor];
self.scaleMode = SKSceneScaleModeAspectFit;
}
Try changing this
_spriteView = (SKView *)self.view;
to
_spriteView = (SKView *)self.targetScene;
Related
How can I get this kind of method refactored better?
This is just a sample in my objective-c project, and I am trying to do it all programmatically
Im not sure what the best practices would be, create a protocol? an extension? or refactor further down to additional methods?
- (void)viewDidLoad {
[super viewDidLoad];
// Label to be changed
label = [[UILabel alloc]init];
label.text = #"Changed with code!";
[self.view addSubview:label];
// Label Constraints
label.translatesAutoresizingMaskIntoConstraints = NO;
[label.topAnchor constraintEqualToAnchor: self.view.safeAreaLayoutGuide.topAnchor constant:50].active = YES;
[label.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor constant:20].active = YES;
[label.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor constant:-20].active = YES;
}
As an example you could create a UIView subclass that creates the label and makes the layout.
#interface MyView: UIView
#property (nonatomic, strong, readonly) UILabel *label;
#end
#interface ViewController: UIViewController
#property (nonatomic, strong, readonly) MyView *myView;
#end
#implementation MyView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_label = [[UILabel alloc] initWithFrame:CGRectZero];
_label.translatesAutoresizingMaskIntoConstraints = NO;
UILayoutGuide *safeAreaLayoutGuide = self.safeAreaLayoutGuide;
[NSLayoutConstraint activateConstraints:#[
[label.topAnchor constraintEqualToAnchor: safeAreaLayoutGuide.topAnchor constant:50],
[label.leadingAnchor constraintEqualToAnchor:safeAreaLayoutGuide.leadingAnchor constant:20],
[label.trailingAnchor constraintEqualToAnchor:safeAreaLayoutGuide.trailingAnchor constant:-20]
]];
}
return self;
}
#end
#implementation MyViewController
- (void)loadView {
self.view = [[MyView alloc] initWithFrame:CGRectZero];
}
- (MyView *)myView {
return (id)self.view; // it makes view to load regardless which
// property do you use – `view` or `myView`
}
- (void)viewDidLoad {
[super viewDidLoad];
self.myView.label.text = #"Changed with code!";
}
#end
I've a NSButton with both an Image and Alternate Image. I would like the alternate image to be shown on hover. To solve this, I've extended the NSButton to show the alternate image when hovering the view. Is there a better solution to this?
My solution:
#interface HoverButton()
#property (nonatomic, strong) NSTrackingArea *trackingArea;
#property (nonatomic, strong) NSImage *imageTmp;
#end
#implementation HoverButton
-(void)mouseEntered:(NSEvent *)theEvent {
[super mouseEntered:theEvent];
[self updateImages];
self.image = self.alternateImage;
}
-(void)mouseExited:(NSEvent *)theEvent {
[super mouseExited:theEvent];
self.image = self.imageTmp;
}
- (void)updateImages {
self.imageTmp = self.image;
}
-(void)updateTrackingAreas
{
if(self.trackingArea != nil) {
[self removeTrackingArea:self.trackingArea];
}
int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways);
self.trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
options:opts
owner:self
userInfo:nil];
[self addTrackingArea:self.trackingArea];
}
#end
I would say this is better suited to an NSButtonCell subclass. you can do it in one method and it won't apply to all NSButtons (I doubt thats what you actually want). Just set your button cell type in IB to your custom subclass.
here is some code I just wrote and tested that works:
- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
if (_alternateImageOrKeyEquivalentFont && _bcFlags2.mouseInside) {
// the draw bezel call is optional. maybe you don't want it
[self drawBezelWithFrame:cellFrame inView:controlView];
[self drawImage:_alternateImageOrKeyEquivalentFont
withFrame:cellFrame
inView:controlView];
} else {
[super drawInteriorWithFrame:cellFrame
inView:controlView];
}
}
you will need to set the showsBorderOnlyWhileMouseInside to YES probably in an init method for the cell.
CustomButton.h
#interface CustomButton : NSButton
#property (getter=isMouseInside) BOOL mouseInside;
#end
CustomButton.m
#implementation CustomButton
+ (Class)cellClass
{
return [CustomButtonCell class];
}
- (instancetype)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
[self commonCustomButtonInit];
}
return self;
}
- (void)commonCustomButtonInit
{
NSTrackingArea *trackingArea = nil;
trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingInVisibleRect
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
}
- (void)mouseEntered:(NSEvent *)event
{
self.mouseInside = YES;
if ([self.cell isKindOfClass:[CustomButtonCell class]])
{
CustomButtonCell *cell = self.cell;
cell.mouseInside = YES;
}
}
-(void)mouseExited:(NSEvent *)event
{
self.mouseInside = NO;
if ([self.cell isKindOfClass:[CustomButtonCell class]])
{
CustomButtonCell *cell = self.cell;
cell.mouseInside = NO;
}
}
#end
CustomButtonCell.h
#interface CustomButtonCell : NSButtonCell
#property (getter=isMouseInside) BOOL mouseInside;
#end
CustomButtonCell.m
#implementation CustomButtonCell
#end
Also see this answer.
I want to implement iAd in my viewController so that i created the singleton class for iAd here the code that i used but it doesnt display iAd in my viewController.
adWhirlSingleton.h
#import <Foundation/Foundation.h>
#import "iAd/ADBannerView.h"
#interface adWhirlSingleton : NSObject <ADBannerViewDelegate> {
ADBannerView *adView;
UIViewController *displayVC;
}
#property (strong, nonatomic) ADBannerView *adView;
#property (strong, nonatomic) UIViewController *displayVC;
+(id)sharedAdSingleton;
-(void)adjustAdSize:(CGFloat)x:(CGFloat)y;
#end
adWhirlSingleton.m
#import "adWhirlSingleton.h"
#implementation adWhirlSingleton
static adWhirlSingleton* _sharedAdSingleton = nil;
#synthesize adView, displayVC;
+(id)sharedAdSingleton
{
#synchronized(self)
{
if(!_sharedAdSingleton)
_sharedAdSingleton = [[self alloc] init];
return _sharedAdSingleton;
}
return nil;
}
+(id)alloc
{
#synchronized([adWhirlSingleton class])
{
NSAssert(_sharedAdSingleton == nil, #"Attempted to allocate a second instance of a singleton.");
_sharedAdSingleton = [super alloc];
return _sharedAdSingleton;
}
return nil;
}
-(id)init
{
self = [super init];
if (self != nil) {
// initialize stuff here
self.adView.delegate=self;
}
return self;
}
-(void)dealloc
{
displayVC = nil;
if (adView) {
[adView removeFromSuperview]; //Remove ad view from superview
[adView setDelegate:nil];
adView = nil;
}
[super dealloc];
}
-(void)adjustAdSize:(CGFloat)x :(CGFloat)y
{
[UIView beginAnimations:#"AdResize" context:nil];
[UIView setAnimationDuration:0.7];
adView.frame = CGRectMake(x, y, 320, 50);
[UIView commitAnimations];
}
-(BOOL)adWhirlTestMode
{
return YES;
}
-(NSString *)adWhirlApplicationKey
{
return #"xxxxxxxxxxxxx";
}
-(UIViewController *)viewControllerForPresentingModalView
{
return displayVC;
}
-(void)bannerViewDidLoadAd:(ADBannerView *)banner {
[self adjustAdSize:0 :410];
}
#end
myViewController.m
#import "adWhirlSingleton.h"
-(void)viewWillAppear:(BOOL)animated {
adWhirlSingleton *adWhirlSingle = [adWhirlSingleton sharedAdSingleton];
adWhirlSingle.displayVC = self;
[adWhirlSingle adjustAdSize:0 :self.view.frame.size.height -50];
[self.view addSubview:adWhirlSingle.adView];
[self.view bringSubviewToFront:adWhirlSingle.adView];
NSLog(#"Ad Banner View");
}
This is how i implemented the singleton class for iAd when i excute this i didnt get iAd displayed over my ViewController.
If anyone know how to implement this please help me to get out of this issue. Thanks in Advance.
I have a custom view that I'm using in a xib file. I load the view and add it to a window. It adds the view just fine as I can see the default text of the labels in the view, but when I try to change the label with a method call, it doesn't change the text.
The custom view isn't anything to fancy, just draws a rounded, transparent background.
NotificationView.h
#import <Cocoa/Cocoa.h>
#interface NotificationView : NSView
#property (weak) IBOutlet NSTextField *primaryLabel;
#property (weak) IBOutlet NSTextField *secondaryLabel;
#property (weak) IBOutlet NSTextField *identifierLabel;
#end
NotificationView.m
#implementation NotificationView
#synthesize primaryLabel;
#synthesize secondaryLabel;
#synthesize identifierLabel;
- (id) initWithFrame:(NSRect)frameRect
{
self = [super initWithFrame:frameRect];
if (self)
{
return self;
}
return nil;
}
- (void)drawRect:(NSRect)dirtyRect
{
NSColor *bgColor = [NSColor colorWithCalibratedWhite:0.0 alpha:0.6];
NSRect rect = NSMakeRect([self bounds].origin.x + 3, [self bounds].origin.y + 3, [self bounds].size.width - 6, [self bounds].size.height - 6);
NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:rect xRadius:5.0 yRadius:5.0];
[path addClip];
NSShadow *shadow = [[NSShadow alloc] init];
[shadow setShadowColor:[NSColor redColor]];
[shadow setShadowBlurRadius:2.0f];
[shadow setShadowOffset:NSMakeSize(0.f, -1.f)];
[shadow set];
[bgColor set];
NSRectFill(rect);
[super drawRect:dirtyRect];
}
#end
In the xib I have a custom view set to the type NotificationView. I've added 3 labels to the view and connected them to the above IBOutlets. (I ctrl-click & drag from the label to the .h file to make the connection.)
I'm loading the view and adding it to a window with the following method. It looks through an array of windows, if an existing match is found it used that window, if not it creates a new window.
- (void) popupNotificationWithTag:(NSString *)tag fade:(double)msFade lineOne:(NSString *)lineOneText lineTwo:(NSString *)lineTwoText
{
NotificationWindow *notificationWindow;
NotificationWindow *tmpWindow;
NSEnumerator *enumerator;
// Walk the notification windows in the array
enumerator = [self.notificationWindows objectEnumerator];
if(enumerator)
{
while((tmpWindow = [enumerator nextObject]))
{
if([tmpWindow.tag isEqualToString:tag])
{
notificationWindow = tmpWindow;
}
}
}
// Make a new notification window
if (!notificationWindow)
{
int width = [[NSScreen mainScreen] frame].size.width;
int height = [[NSScreen mainScreen] frame].size.height;
notificationWindow = [[NotificationWindow alloc] initWithRect:NSMakeRect(width - 420, height - 130, 400, 100)];
NSNib *nib = [[NSNib alloc] initWithNibNamed:#"Notification" bundle: nil];
NSArray *objects;
[nib instantiateNibWithOwner:self topLevelObjects:&objects];
for (id obj in objects) {
if ([[obj class] isSubclassOfClass:[NSView class]])
[notificationWindow setContentView:obj];
}
[notificationWindow setTag:tag];
[self.notificationWindows addObject:notificationWindow];
}
// Display window
[notificationWindow makeKeyAndOrderFront:nil];
[notificationWindow display];
notificationWindow.fadeOut = msFade;
[notificationWindow setPrimaryText:lineOneText];
[notificationWindow setSecondaryText:lineTwoText];
[notificationWindow setIdentifierText:tag];
}
The window class is NotificationWindow.h
#import <Foundation/Foundation.h>
#interface NotificationWindow : NSWindow
#property (nonatomic, strong) NSString *tag;
#property (nonatomic) double fadeOut;
- (id)initWithRect:(NSRect)contentRect;
- (void) setPrimaryText:(NSString *)text;
- (void) setSecondaryText:(NSString *)text;
- (void) setIdentifierText:(NSString *)text;
#end
NotificationWindow.m
#import "NotificationWindow.h"
#import "NotificationView.h"
//===========================================================================================================================
// Private call properties and methods
//===========================================================================================================================
#interface NotificationWindow()
#property (nonatomic,strong) NSTimer *timerFade;
- (void) timerFadeFired;
#end
//===========================================================================================================================
//===========================================================================================================================
#implementation NotificationWindow
//===========================================================================================================================
// Property Getters and Setters
//===========================================================================================================================
#synthesize tag = _tag;
#synthesize fadeOut = _fadeOut;
#synthesize timerFade = _timerFade;
//===========================================================================================================================
// Public methods
//===========================================================================================================================
- (id)initWithRect:(NSRect)contentRect
{
if (self = [super initWithContentRect:contentRect
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO]) {
[self setLevel: NSScreenSaverWindowLevel];
[self setBackgroundColor: [NSColor clearColor]];
[self setAlphaValue: 1.0];
[self setOpaque: NO];
[self setHasShadow: NO];
[self setIgnoresMouseEvents: YES];
[self setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces];
[self orderFront: NSApp];
self.fadeOut = -1;
// Start our timer to deal with fadeing the window
self.timerFade = [NSTimer scheduledTimerWithTimeInterval:0.001
target:self
selector:#selector(timerFadeFired)
userInfo:nil
repeats:YES];
return self;
}
return nil;
}
- (BOOL) canBecomeKeyWindow
{
return YES;
}
- (void) display
{
[super display];
[self setAlphaValue:1.0];
}
- (void) setPrimaryText:(NSString *)text
{
NotificationView *view = self.contentView;
view.primaryLabel.stringValue = text;
}
- (void) setSecondaryText:(NSString *)text
{
NotificationView *view = self.contentView;
view.secondaryLabel.stringValue = text;
}
- (void) setIdentifierText:(NSString *)text
{
NotificationView *view = self.contentView;
view.identifierLabel.stringValue = text;
}
//===========================================================================================================================
// Private methods
//===========================================================================================================================
- (void) timerFadeFired
{
[self orderFront:NSApp];
if (self.fadeOut > 0)
{
self.fadeOut--;
}
else if (self.fadeOut == 0)
{
if (self.alphaValue > 0)
self.alphaValue -= 0.002;
else
self.fadeOut = -1;
}
}
#end
So I assume I'm doing something wrong connecting the labels to the IBOutlets, but I can't figure out what. I suppose I could create the view in code, but I was trying to be good and use the interface builder.
I'm in XCode 4.2.1.
Hi I am trying to develop a new app on the ipad. I am using a spitTableView and adding a ModalPresentationPage to the view. This works perfectly on the xcode iPad sim but crashes on my iPad. just so you know I am using xcode 5BATA and running IOS 5 on my iPad.
here is my code
DetailViewController.h
#import <UIKit/UIKit.h>
#interface DetailViewController : UIViewController <UISplitViewControllerDelegate>{
}
-(IBAction)loadView:(id)sender;
#property (strong, nonatomic) id detailItem;
#property (strong, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
#property (strong, nonatomic) IBOutlet UIToolbar *toolbar;
#end
DetailViewController.m
#import "DetailViewController.h"
#import "ModalViewController.h"
#import "RootViewController.h"
#interface DetailViewController ()
#property (strong, nonatomic) UIPopoverController *popoverController;
- (void)configureView;
#end
#implementation DetailViewController
#synthesize detailItem = _detailItem;
#synthesize detailDescriptionLabel = _detailDescriptionLabel;
#synthesize toolbar = _toolbar;
#synthesize popoverController = _myPopoverController;
-(IBAction)loadView:(id)sender{
ModalViewController *mvc = [[ModalViewController alloc]initWithNibName:#"modalViewController"bundle:nil];
mvc.modalPresentationStyle = UIModalPresentationPageSheet;
mvc.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:mvc animated:YES];
}
- (id)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
}
return self;
}
#pragma mark - Managing the detail item
- (void)setDetailItem:(id)newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
if (self.popoverController != nil) {
[self.popoverController dismissPopoverAnimated:YES];
}
}
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
self.detailDescriptionLabel.text = [self.detailItem description];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self configureView];
self.splitViewController.delegate = self;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
#pragma mark - Split view
- (void)splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController: (UIPopoverController *)pc
{
barButtonItem.title = #"Master";
NSMutableArray *items = [[self.toolbar items] mutableCopy];
[items insertObject:barButtonItem atIndex:0];
[self.toolbar setItems:items animated:YES];
self.popoverController = pc;
}
- (void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
// Called when the view is shown again in the split view, invalidating the button and popover controller.
NSMutableArray *items = [[self.toolbar items] mutableCopy];
[items removeObjectAtIndex:0];
[self.toolbar setItems:items animated:YES];
self.popoverController = nil;
}
#end
Parts not under NDA :-
You are leaking items in both the split view delegate methods.
Are you sure the XIB name is modalViewController? There could a problem of it being case sensitive on the device.