Objective-c update NSTextField at ControllerView init - objective-c

#interface TestViewController : NSViewController
#property (nonatomic, retain) IBOutlet NSTextField *myLabel;
- (IBAction)sendMessage:(NSButton *)sender;
#end
#implementation TestViewController
#synthesize myLabel = _myLabel;
- (id)init{
self = [super init];
if(self){
[self updateLabel];
}
return self;
}
- (IBAction)sendMessage:(NSButton *)sender {
[self updateLabel];
NSLog(#"Message sent");
}
- (void) updateLabel{
NSLog(#"Update!! %#");
[self.myLabel setStringValue:#"random text"];
}
#end
I want to update an NSTextField when view is displayed, and i put my updateLabel at init in the log i see Update!! but the NSTextField it's not update with my text.
But when i press the button that calls the same updateLabel the NSTextField is updatet. Can someone help me to understand why it's not working as expected ?

I follow the suggestion of #rdelmar to use loadView. Thank you.
And here is how to implement it if anyone interested.
- (void)loadView
{
[super loadView];
[self updateLabel];
}

Related

Custom input view controller

Is it possible to use UIInputViewController subclass as input view on iOS 9? I've tried setting inputViewController property but no custom view controller shows up when my text field becomes a first responder.
#interface InputViewController : UIInputViewController
#end
#implementation InputViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIDatePicker *datePicker = [[UIDatePicker alloc] init];
datePicker.translatesAutoresizingMaskIntoConstraints = NO;
[self.inputView addSubview:datePicker];
[datePicker.leadingAnchor constraintEqualToAnchor:self.inputView.leadingAnchor].active = YES;
[datePicker.trailingAnchor constraintEqualToAnchor:self.inputView.trailingAnchor].active = YES;
[datePicker.topAnchor constraintEqualToAnchor:self.inputView.topAnchor].active = YES;
[datePicker.bottomAnchor constraintEqualToAnchor:self.inputView.bottomAnchor].active = YES;
}
#end
#interface TextField: UITextField
#property (nonatomic, readwrite, strong) UIInputViewController *inputViewController;
#end
#implementation TextField
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.textField.inputViewController = [[InputViewController alloc] init];
}
#end
Turned out the missing piece was:
self.view.translatesAutoresizingMaskIntoConstraints = NO;
Very frustrating that UIInputViewController does not do this automatically.

Xcode: How do I change UIPageControl value with swipe gesture?

I have a quick question I was hoping you guys could help me answer. Right now I have a UIPageControl in a storyboard which changes an image depending on what dot you are on, however, as of now you have to press on the dot to change through the dots/images, how can I change through the images/dots by swiping?
Here is my code for my .h
#import <UIKit/UIKit.h>
#interface PageViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIImageView *dssview;
- (IBAction)changephoto:(UIPageControl *)sender;
#end
Here is my code for my .m
#import "PageViewController.h"
#interface PageViewController ()
#end
#implementation PageViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)changephoto:(UIPageControl *)sender {
_dssview.image = [UIImage imageNamed:
[NSString stringWithFormat:#"%d.jpg",sender.currentPage+1]];
}
#end
Any help would be greatly appreciated.
Thanks
You can add UISwipeGestureRecognizer to your view and in the selector method of UISwipeGestureRecognizer based on the direction update the UIPageControl object, either increment the current page or decrement.
You can refer the below code.
Adding swipe gesture to the view controller
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipe:)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:swipeLeft];
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipe:)];
swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:swipeRight];
Swipe gesture selector
- (void)swipe:(UISwipeGestureRecognizer *)swipeRecogniser
{
if ([swipeRecogniser direction] == UISwipeGestureRecognizerDirectionLeft)
{
self.pageControl.currentPage -=1;
}
else if ([swipeRecogniser direction] == UISwipeGestureRecognizerDirectionRight)
{
self.pageControl.currentPage +=1;
}
_dssview.image = [UIImage imageNamed:
[NSString stringWithFormat:#"%d.jpg",self.pageControl.currentPage]];
}
Add an outlet to the UIPageControl in the .h file
#interface PageViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIImageView *dssview;
#property (strong, nonatomic) IBOutlet UIPageControl *pageControl;
- (IBAction)changephoto:(UIPageControl *)sender;
#end

Passing value from one class to another, using #property

I have been pulling my hair out all afternoon trying to figure out why the following code will not work. All I am trying to do is pass a string, from one class to another.
In my FirstDetailViewController.h file I declare the NSString
#property(nonatomic, retain) NSString *infoForArray;
And then in my Grinding01_DetailViewController.m I try to set a value for the string
#import "Grinding01_DetailViewController.h"
#import "FirstDetailViewController.h"
#implementation Grinding01_DetailViewController
...
NSString *didLoadMessage = #"Grinding01 Loaded";
FirstDetailViewController *temp = [[FirstDetailViewController alloc] initWithNibName:#"FirstDetailView" bundle:nil];
temp.infoForArray = didLoadMessage;
[self.navigationController pushViewController:temp animated:YES];
}
When I output the infoForArray from the FirstDetailViewController.h it is null.
Any help would be appreciated, I think there's a simple step that I am missing, but I just can't see it.
EDIT: Here is the code from the FirstDetailViewController
FirstDetailViewController.h
#import <UIKit/UIKit.h>
#import "Protocols.h"
#interface FirstDetailViewController : UIViewController <SubstitutableDetailViewController> {
//for the output
IBOutlet UITextView *outputView;
UIToolbar *navigationBar;
NSMutableArray *logMessages;
}
#property (nonatomic, retain) IBOutlet UIToolbar *navigationBar;
//for incoming messages
#property(nonatomic, retain) NSString *infoForArray;
#end
FirstDetailViewController.m
#import "FirstDetailViewController.h"
#implementation FirstDetailViewController
#synthesize navigationBar, infoForArray;
-(void)viewDidLoad{
[super viewDidLoad];
//The log cannot be changed
outputView.editable = NO;
}
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidUnload {
[super viewDidUnload];
self.navigationBar = nil;
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];
NSLog(#"message: %#", infoForArray);
outputView.text = infoForArray;
}
#pragma mark -
#pragma mark Managing the popover
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem {
// Add the popover button to the toolbar.
NSMutableArray *itemsArray = [navigationBar.items mutableCopy];
[itemsArray insertObject:barButtonItem atIndex:0];
[navigationBar setItems:itemsArray animated:NO];
[itemsArray release];
}
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem {
// Remove the popover button from the toolbar.
NSMutableArray *itemsArray = [navigationBar.items mutableCopy];
[itemsArray removeObject:barButtonItem];
[navigationBar setItems:itemsArray animated:NO];
[itemsArray release];
}
#pragma mark -
#pragma mark Rotation support
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
#pragma mark -
#pragma mark Memory management
- (void)dealloc {
[navigationBar release];
[super dealloc];
}
#end
It sounds like the trouble area is in in FirstDetailViewController. I would suggest posting the code for that so we can see what's going on.
my guess is you are checking for infoForArray somewhere in the instantiation process of FirstDetailViewController, which occurs before you set temp.infoForArray = didLoadMessage.
Just for reference, if you check for infoForArray in viewDidLoad that will be too early. viewDidLoad is triggered when the view is put into memory. What you want is viewDidAppear, which you may have to add yourself

How to pass Arrays to a UIPickerView from one class to another?

Bah. I've pulled my hair out over this problem for the past couple days now, but I know I must be overlooking the obvious. I've made my PickerViewController(.h./m) and PickerViewAppDelegate(.h/.m) files and they run fine as a standalone program, but I would like to have the picker pop up after a procedureal event occurs in my "helloworld.m" file. I can get the picker to show up, but I cannot for the life of me figure out how to populate it so that it isn't blank. I THINK I've done everything right up until I try to pass my array to my pickerview object. What am I doing wrong?
PickerViewController.h
#import <UIKit/UIKit.h>
#interface PickerViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate> {
IBOutlet UIPickerView *pickerView;
NSMutableArray *scrollerData;
}
#property (nonatomic, retain) IBOutlet UIPickerView *pickerView;
#property (nonatomic, retain) NSMutableArray *scrollerData;
-(void)setScrollerData:(NSMutableArray *)array;
#end
PickerViewController.m
#import "PickerViewController.h"
#implementation PickerViewController
#synthesize pickerView, scrollerData;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
self.pickerView.delegate = self;
self.pickerView.dataSource = self;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
- (void)dealloc {
// [arrayColors release];
[super dealloc];
}
-(void)setScrollerData:(NSMutableArray *)array
{
//[self.scrollerData arrayByAddingObjectsFromArray:array];
scrollerData = array;
}
#pragma mark -
#pragma mark Picker View Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
return [scrollerData count];
}
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [scrollerData objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSLog(#"Selected Number: %#. Index of selected numbers: %i", [scrollerData objectAtIndex:row], row);
}
PickerViewAppDelegate.h
#import <UIKit/UIKit.h>
#class PickerViewController;
#interface PickerViewAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
PickerViewController *pvController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
PickerViewAppDelegate.m
#import "PickerViewAppDelegate.h"
#import "PickerViewController.h"
#implementation PickerViewAppDelegate
#synthesize window;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
pvController = [[PickerViewController alloc] initWithNibName:#"PickerView" bundle:[NSBundle mainBundle]];
[window addSubview:pvController.view];
// Override point for customization after application launch
[window makeKeyAndVisible];
}
- (void)dealloc {
[pvController release];
[window release];
[super dealloc];
}
#end
Helloworld.m
...
UIView* view = [[CCDirector sharedDirector] openGLView];
UIPickerView *pickerView=[[UIPickerView alloc] init];
pickerView.frame=CGRectMake(100,100, 200, 200);
NSMutableArray *arrayNumbers = [[NSMutableArray alloc] init];
[arrayNumbers addObject:#"30"];
[arrayNumbers addObject:#"31"];
[arrayNumbers addObject:#"32"];
[arrayNumbers addObject:#"33"];
[arrayNumbers addObject:#"34"];
[arrayNumbers addObject:#"35"];
[arrayNumbers addObject:#"36"];
[pickerView setscrollerData: arrayNumbers];//Should I be calling pickerView here or something else?
[view addSubview: pickerView];
pickerView.hidden=NO;
...
You have overridden the setter method generated by #synthesize in PickerViewController, so you are no longer retaining it.
Then, you are calling setScrollerData on your pickerView (this should be giving you a warning or crashing since pickerView doesn't respond to that method).
You are not setting PickerViewController as the delegate or datasource of your picker view in helloworld.m.
I can't see where your hello world code fits in. It seems to be adding a new picker view rather than using the one from the xib of PickerViewController. You should be instantiating pickerviewcontroller from your hello world and adding its .view as a subview or presenting it as a modal view controller rather than setting up a new picker view. You can then pass your array to the instance of pickerviewcontroller. Note though that it is not standard to have a separate view controller for what is essentially a subview, though I don't have much knowledge of cocos2d so I don't know if this is normal when using that framework.
Well, i think you should just pass the array from HelloWorld class to PickerViewController class using property/synthesize.

EXC_BAD_ACCESS when I change moviePlayer contentURL

In few words, my application is doing that :
1) My main view (RootViewController) has a buton when I tap on it, it displays the player (PlayerViewController) :
2) In my Player, I initialize the video I want to play
-> It's working good, my movie is display
My problem :
When I go back to my main view :
And I tap again on the button, I get a *Program received signal: “EXC_BAD_ACCESS”.*
If I comment self.player.contentURL = [self movieURL]; it's working, but when I let it, iI have this problem.
I read that it's due to null pointer or memory problem but I don't understand why it's working the first time and not the second time. I release my object in dealloc method.
Thanks for your help !
Bruno.
Here is my code :
Root View Controller
RootViewController.h
#import <UIKit/UIKit.h>
#import "PlayerViewController.h"
#interface RootViewController : UIViewController {
IBOutlet UIButton * myButton;
}
#property (nonatomic,retain) IBOutlet UIButton * myButton;
-(IBAction)displayPlayer:(id)sender;
- (void) returnToRoot: (PlayerViewController *) controller;
#end
RootViewController.m
#import "RootViewController.h"
#implementation RootViewController
#synthesize myButton;
-(IBAction)displayPlayer:(id)sender
{
PlayerViewController *playerViewController = [[PlayerViewController alloc] initWithNibName:#"PlayerViewController" bundle:nil];
playerViewController.delegate = self;
playerViewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController: playerViewController animated: YES];
[playerViewController release];
}
- (void) returnToRoot: (PlayerViewController *) controller
{
[self dismissModalViewControllerAnimated: YES];
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)dealloc {
[super dealloc];
}
#end
Player View Controller
PlayerViewController.h
#import <UIKit/UIKit.h>
#import <MediaPlayer/MPMoviePlayerController.h>
#protocol PlayerViewControllerDelegate;
#interface PlayerViewController : UIViewController {
UIView *viewForMovie;
MPMoviePlayerController *player;
}
#property (nonatomic, assign) id <PlayerViewControllerDelegate> delegate;
#property (nonatomic, retain) IBOutlet UIView *viewForMovie;
#property (nonatomic, retain) MPMoviePlayerController *player;
- (NSURL *)movieURL;
-(IBAction)goBackToRoot:(id)sender;
#end
#protocol PlayerViewControllerDelegate
- (void) returnToRoot: (PlayerViewController *) controller;
#end
PlayerViewController.m
#import "PlayerViewController.h"
#implementation PlayerViewController
#synthesize player;
#synthesize viewForMovie;
#synthesize delegate;
- (void)dealloc {
[super dealloc];
[player release];
[viewForMovie release];
}
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"viewDidLoad");
self.player = [[MPMoviePlayerController alloc] init];
[self.player autorelease];
self.player.view.frame = self.viewForMovie.bounds;
self.player.view.autoresizingMask =
UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight;
[self.viewForMovie addSubview:player.view];
self.player.contentURL = [self movieURL];
[self.player play];
}
-(NSURL *)movieURL
{
NSBundle *bundle = [NSBundle mainBundle];
NSString *moviePath =
[bundle
pathForResource:#"myVideo"
ofType:#"mp4"];
if (moviePath) {
return [NSURL fileURLWithPath:moviePath];
} else {
return nil;
}
}
-(IBAction)goBackToRoot:(id)sender{
[self.delegate returnToRoot: self];
}
- (void)viewDidUnload {
[super viewDidUnload];
}
#end
Problem
The second time I call "displayPlayer" I had the EXC_BAD_ACCESS
I solved it !!!
I look on the MPMoviePlayerController to see what kind of variable is contentURL
(NSURL *)contentURL
It means I have also to liberate it.
I do that in my dealloc method putting a nil value:
-(void) dealloc {
[super dealloc];
self.player.contentURL = nil;
[player release];
[viewForMovie release];
}
If I comment self.player.contentURL =
[self movieURL]; it's working, but
when I let it, iI have this problem.
In that case, how is contentURL declared? Does the #property definition include copy or retain?