Refactoring after changing local variable into instance variable - objective-c

Am having some trouble with my code after changing a local variable into an instance variable. To be specific, I have been having trouble with my code in my HypnosisterAppDelegate.m file after changing one line of code from:
HypnosisView *view = [[HypnosisView alloc]initWithFrame:screenRect];
to
view = [[HypnosisView alloc]initWithFrame:screenRect];
I have commented out the error messages in HypnosisterAppDelegate.m Can you tell me what's wrong? Thanks in advance.
HypnosisterAppDelegate.m
#import "HypnosisterAppDelegate.h"
#import "HypnosisView.h"
#implementation HypnosisterAppDelegate
#synthesize window = _window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
CGRect screenRect = [[self window]bounds];
// Create the UIScrollView to have the size of a window, matching its size
view = [[HypnosisView alloc]initWithFrame:screenRect];
[scrollView setMinimumZoomScale:1.0]; // Unknown receiver "scrollView"; should it be "UIScrollView"?
[scrollView setMaximumZoomScale:5.0]; // Unknown receiver "scrollView"; should it be "UIScrollView"?
//You will get a warning here, ignore it for now
[scrollView setDelegate:self]; // Unknown receiver "scrollView"; should it be "UIScrollView"?
[[self window] addSubview:scrollView]; // Unknown receiver "scrollView"; should it be "UIScrollView"?
//Create the HypnosisView with a frame that is twice the size of the screen
CGRect bigRect = screenRect;
HypnosisView *view = [[HypnosisView alloc]initWithFrame:screenRect];
// Add the HypnosisView as a subview of the scrollView instead of the window
[scrollView addSubview:view]; // Unknown receiver "scrollView"; should it be "UIScrollView"?
// Tell the scrollView how big its virtual world is
[scrollView
setContentSize:bigRect.size]; // Unknown receiver "scrollView"; should it be "UIScrollView"?
BOOL success = [view becomeFirstResponder];
if (success) {
NSLog(#"HypnosisView became the first responder");
} else {
NSLog(#"Could not become the first responder");
}
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return view;
}
#end
HypnosisView.h
#import <Foundation/Foundation.h>
#interface HypnosisView : UIView {
}
#property(nonatomic,strong)UIColor *circleColor;
#end

You don't have a variable called scrollView anywhere. I'd guess (especially from the comment // Create the UIScrollView to have the size of a window, matching its size, and also having gone through this book myself) that you meant to create a UIScrollView:
// not: view = [[HypnosisView alloc]initWithFrame:screenRect];
// but:
UIScrollView * scrollView = [[UIScrollView alloc] initWithFrame:screenRect];
and then add your HypnosisView later as a subview.

Related

OS X how to designate startup viewcontroller

I am developing a simple browser project on mac, i didn't use the default viewcontroller.
Instead, I write a viewcontroller class BrowserViewController.
and write follow in appdelegate
#interface AppDelegate()
#property (nonatomic, strong) BrowserViewController *browserController;
#end
#implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
self.browserController = [[BrowserViewController alloc] init];
[self.window makeKeyWindow];
[self.window setContentView:self.browserController.view];
}
#end
But when the app start up it lead to the default viewcontroller not the BrowserViewController. I really don't know the reason.
Thanks for the help, i have solve this problem. My solution is like this:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
//set the frame of the window fit to the device's frame
//
self.window = [[NSWindow alloc] initWithContentRect:[[NSScreen mainScreen] frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO ];
//
//
self.browserController = [[BrowserViewController alloc] init];
//set contentView
//
self.window.contentViewController = self.browserController;
//this is setting global backgroundColor of the window
//
self.window.backgroundColor = [NSColor whiteColor];
//this means the window is the window that will receive user interaction.
//
[self.window makeKeyAndOrderFront:self];
//[self.window makeKeyWindow];//NOTE: This is not working.
}
You can select Is Initial Controller in the storyboard.
Sounds like you're looking for (inside your didFinishLaunchingWithOptions method):
self.browserController = [[BrowserViewController alloc] init];
[self.window setRootViewController: self.browserController];
[self.window makeKeyAndVisible];
If you want it programmatically:
Note
This is for iOS, but the logic are identical. Hope this will be useful for some reason.. :)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//set the frame of the window fit to the device's frame
//
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
//what you have above is correct
//
self.browserController = [[BrowserViewController alloc] init];
//you can also directly set it like
//
BrowserViewController *mainView = [[BrowserViewController alloc] init];
//this is the most important, you need to set the window's rootViewController
//
self.window.rootViewController = mainView;
//this is setting global backgroundColor of the window
//
self.window.backgroundColor = [UIColor whiteColor];
//this means the window is the window that will receive user interaction.
//
[self.window makeKeyAndVisible];
return YES;
}
Hope this is helpful and informative.. Cheers! :)

RectView doesn't move away from UIWindow

I have the following simple code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
CGRect firstFrame = CGRectMake(300, 300, 150, 259); //CGRect is a struct not a simple object
ExampleView *view = [[ExampleView alloc] initWithFrame:firstFrame]; //crea la view
view.backgroundColor = [UIColor redColor]; //colora la view
[self.window addSubview:view];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
I'm working on XCode 5.1.1 but problem is that the red rect it is showed remains in the same position despite changing the values in CGRectMake. Do you have any idea why?
EDIT
This is the code
#import "ExampleView.h"
#implementation ExampleView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
#end

initWithFrame is filling the screen instead of creating a frame of the size I want

I'm new to Cocoa development and suspect that this is a noob issue.
I'm creating a simple background canvas with a bespoke UIView. I was expecting that I would be able to create this canvas to be slightly indented down from the main view so that I could add a toolbar at a later date. However, when I use initWithFrame (and any other init for that matter), the canvas is always created to be the size of the full screen rather than slightly smaller than the full screen. Even if I completely override the values for CGRect it doesn't make a difference. I've set a touchesBegan event and set the background colour to green to be able to determine success but all I get are a completely green screen and a touch event that works everywhere.
Please help - this is driving me mad and I can't find the answer anywhere on the web.
The relevant code is as follows (there actually isn't much more code than this in the whole app so far):
AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.objMainViewController = [[MainViewController alloc] init];
self.window.rootViewController = self.objMainViewController;
[self.window makeKeyAndVisible];
return YES;
}
MainViewController.h
#import <UIKit/UIKit.h>
#import "viewCanvas.h"
#interface MainViewController : UIViewController
#property (strong, nonatomic) viewCanvas *objViewCanvas;
-(id)init;
#end
MainViewController.m
#import "MainViewController.h"
#import "viewCanvas.h"
#implementation MainViewController
#synthesize objViewCanvas;
-(id)init
{
if (self = [super init]) {
CGRect frame = CGRectMake(100, 100, 100, 100);
objViewCanvas = [[viewCanvas alloc] initWithFrame:frame];
}
return self;
}
- (void)loadView {
self.view = objViewCanvas;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
viewCanvas.h
#import <UIKit/UIKit.h>
#import "viewCanvas.h"
#interface viewCanvas : UIView {
}
//Init
- (id) initWithFrame:(CGRect)frame;
//Events
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
#end
viewCanvas.m
#import "viewCanvas.h"
#implementation viewCanvas
//Standard inits
- (id) initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
[self setBackgroundColor:[UIColor greenColor]];
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Touches Began Canvas" message:#"Canvas Touches Began" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles: nil];
[alert show];
}
#end
I think by default the view of a view controller fills the whole screen, so you need to add a subview to that view that's your smaller viewCanvas object (BTW, you should conform to the naming rules and name your classes with capital letters, ViewCanvas). Try this in your MainViewController .m file:
-(id)init{
if (self = [super init]) {
CGRect frame = CGRectMake(100, 100, 100, 100);
objViewCanvas = [[ViewCanvas alloc] initWithFrame:frame];
self.contentView = [[UIView alloc] initWithFrame:CGRectMake(1, 1, 1, 1)]; //this frame doesn't matter
[self.contentView setBackgroundColor:[UIColor whiteColor]];
}
return self;
}
- (void)loadView {
self.view = self.contentView;
[self.view addSubview:objViewCanvas];
}

Can't return firstResponder status

Have set up my appDelegate to return a firstResponder status, but when I compile (it compiles fine), the console returns "Could not become the first responder" but doesn't tell why.
I have attached the code. Can you tell me what's wrong? Thanks in advance.
HypnosisterAppDelegate.m
#import "HypnosisterAppDelegate.h"
#import "HypnosisView.h"
#implementation HypnosisterAppDelegate
#synthesize window = _window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
HypnosisView *view = [[HypnosisView alloc] initWithFrame:[[self window]bounds]];
[[self window]addSubview:view];
BOOL success = [view becomeFirstResponder];
if (success) {
NSLog(#"HypnosisView became the first responder");
} else {
NSLog(#"Could not become the first responder");
}
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
-(BOOL)canBecomeFirstResponder
{
return YES;
}
You've implemented canBecomeFirstResponder on HypnosisterAppDelegate, which is not a UIResponder sub-class. You then send becomeFirstResponder to your custom view (HypnosisView).
HypnosisView (not the HypnosisterAppDelegate) needs to do this:
-(BOOL)canBecomeFirstResponder
{
return YES;
}

BookController in iOS 5 Developer's Cookbook (Erica Sadun) does not start correctly in landscape mode

The problem I'm trying to solve:
I used chapter 05 example 06 BookController in chapter 5 (C05/06-Scrubbing Pages in https://github.com/erica/iOS-5-Cookbook.git ) in a project that have a UInavigatioController as rootViewController, but it does not start correctly in landscape mode. If you rotate the device portrait and return to landscape it begins to work.
To show the bug modify the example test bed delegate in main.c with the following:
#pragma mark Application Setup
#interface TestBedAppDelegate : NSObject <UIApplicationDelegate>
{
UIWindow *window;
}
#end
#implementation TestBedAppDelegate
TestBedViewController *tbvc;
UINavigationController *navigationController;
- (void) pushBookController: (UIGestureRecognizer *) recognizer
{
[navigationController pushViewController:tbvc animated:YES];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
tbvc = [[TestBedViewController alloc] init];
UIViewController *start = [tbvc controllerWithColor:[UIColor whiteColor] withName:#"white"];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(pushBookController:)];
[start.view addGestureRecognizer:tap];
navigationController = [[UINavigationController alloc] initWithRootViewController:start];
window.rootViewController = navigationController;
[window makeKeyAndVisible];
return YES;
}
#end
My application starts landscape, so the problem is that the book controller does not recognize landscape mode at start (if you rotate after start it will work). Try it.
To recognize landscape at start, substitute in BookController the following method
// Entry point for external move request
- (void) moveToPage: (uint) requestedPage
{
//[self fetchControllersForPage:requestedPage orientation:(UIInterfaceOrientation)[UIDevice currentDevice].orientation];
[self fetchControllersForPage:requestedPage orientation:self.interfaceOrientation];
}
and add the following:
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {return YES;}
Now the problem is that BookController does not appear at start, but again if you rotate it begins to work.
probably you solved this already, but try changing the Book's instantiation like this:
+ (id) bookWithDelegate: (id) theDelegate
{
NSDictionary *options = nil;
//Check the orientation
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
//Setting Spine Location to middle for Landscape orientation
options = [NSDictionary dictionaryWithObject:
[NSNumber numberWithInteger:UIPageViewControllerSpineLocationMid]
forKey: UIPageViewControllerOptionSpineLocationKey];
}
BookController *bc = [[BookController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:options];
bc.dataSource = bc;
bc.delegate = bc;
bc.bookDelegate = theDelegate;
return bc;
}
Note that I'm adding a statusBarOrientation check to set the spine.
Basically what you need is to check the orientation when you're creating the UIPageViewController, and I used the statusBarOrientation.
Oh, and don't forget to ensure you're getting the right orientation
- (BOOL) useSideBySide: (UIInterfaceOrientation) orientation
{
BOOL isLandscape = UIInterfaceOrientationIsLandscape(orientation);
// in case the UIInterfaceOrientation is 0.
if (!orientation) {
isLandscape = UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]);
}
return isLandscape;
}
ps: The bookWithDelegate method corresponds to the BookController class within the example mentioned in the question.