Initialization of controls in custom uiview - iphone

I've created a custom uiview in IB and set the class for it.
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#interface myView : UIControl {
IBOutlet UITextView *textView;
}
#end
#import "myView.h"
#implementation myView
- (void)commonInit
{
[textView setText:#"lajsdfklasdfjl"];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder])
{
[self commonInit];
}
return self;
}
-(id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
[self commonInit];
}
return self;
}
#end
I put a textview with text on this view in IB and linked it to IBOutlet IUTextView *textView.
When I drag this custom view on my UIViewController (from classes tab in IB's library) the view is empty.
- (id)initWithCoder:(NSCoder *)aDecoder is calling but the textView is null.
What is wrong? Thanks

As far as I remember, the hierarchy is not properly set up in init, as the properties can only be set after init has finished.
You want to use
-(void)awakeFromNib
{
[super awakeFromNib];
[self commonInit];
}
instead and remove the initWithCoder: thing altogether.
As a side note, you should let your class names begin with upper case letters.

There should be nothing stopping you from using a custom UIViewController which has methods built in for initializing or deallocating the UIView that it contains. I found this to be a simpler solution. For example, you can set up your custom UIViewController using a nib with a UIView, then make sure your File's Owner is set to the custom class.
You can then remove the following 3 instance methods
- (void)commonInit
- (id)initWithCoder:(NSCoder *)aDecoder
- (id)initWithFrame:(CGRect)frame
and in your custom UIViewController class use initWithNibName as below
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
self.view.frame = CGRectMake(0, 44, self.view.frame.size.width, self.view.frame.size.height);
}
return self;
}
This initWithNibName instance method will be called automatically when you alloc your custom UIViewController class like this
CustomUIViewController *vc = [[CustomUIViewController alloc] init];
Put a break point in initWithNibName and you will see it called.

Related

UITextView.text lags when loading text

I want to display text with an UITextView, which is part of an UITabBarView and do so in the following Class:
.h - File:
#import <UIKit/UIKit.h>
#interface DescriptionViewController : UIViewController{
IBOutlet UITextView *descriptionText;
}
#end
.m - File:
#import "DescriptionViewController.h"
#import "Globals.h"
#interface DescriptionViewController ()
#end
#implementation DescriptionViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void) viewWillAppear:(BOOL)animated{
Globals* myGlobals = [Globals sharedGlobals];
descriptionText.text = [myGlobals.currentLine objectAtIndex:5];
}
#end
When the TextView is displayed the first time it is empty, when i switch to another tab and switch back to the "TextView - Tab" it is displayed properly. But I obviously want it to be displayed correctly the first time..
I already tried to move the relevant code to the -viewDidLoad function, but nothing changed. Also, I tried the -setNeedsDisplay function without success (maybe I used it wrong? - [descriptionText setNeedsDisplay].
I appreciate any help and further code will be posted on request.
Please set breakpoint on ViewWillAppear Method of your class then check that in first time what you are getting from NSLog("%#", [myGlobals.currentLine objectAtIndex:5]);
and you are missing [super viewWillAppear:animated];
try this,
- (void)viewDidLoad
{
[super viewDidLoad];
Globals* myGlobals = [Globals sharedGlobals];
descriptionText.text = [myGlobals.currentLine objectAtIndex:5];
}
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
Globals* myGlobals = [Globals sharedGlobals];
descriptionText.text = [myGlobals.currentLine objectAtIndex:5];
}

Passing data between Tabs using delegate not working

I want to pass data from second tab to first tab using delegates.But delegate method not triggered.here is the code (I m using storyboard)
in SecondViewController.h
#import <UIKit/UIKit.h>
#class SecondViewController;
#protocol SecondViewControllerDelegate <NSObject>
-(void) sliderValueDidChanged: (SecondViewController *)controller data:(float) sliderValue;
#end
#interface SecondViewController : UIViewController{
__weak id<SecondViewControllerDelegate> delegate;
}
- (IBAction)sliderPressed:(id)sender;
#property (weak, nonatomic) IBOutlet UISlider *mySlider;
#property(weak,nonatomic) id<SecondViewControllerDelegate> delegate;
#end
in SecondViewController.m
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
#synthesize mySlider;
#synthesize delegate;
- (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)viewDidUnload
{
[self setMySlider:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (IBAction)sliderPressed:(id)sender {
float value = mySlider.value;
[self.delegate sliderValueDidChanged:self data:value];
NSLog(#"%#",self.delegate);
}
#end
FirstViewController.h
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#interface FirstViewController : UIViewController<SecondViewControllerDelegate>
#property (weak, nonatomic) IBOutlet UILabel *myLabel;
#end
in FirstViewController.h
#import "FirstViewController.h"
#interface FirstViewController ()
#end
#implementation FirstViewController
#synthesize myLabel;
- (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.
SecondViewController *svc = [[SecondViewController alloc]init];
svc.delegate = self;
}
- (void)viewDidUnload
{
[self setMyLabel:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(void) sliderValueDidChanged: (SecondViewController *)controller data:(float) sliderValue{
myLabel.text = [[NSString alloc]initWithFormat:#"%f",sliderValue];
NSLog(#"delegate called");
}
#end
I am trying to set a slider in second tab and send the sider value to first tab which has a label. self.delegate printing null and delegate method never called.
Simply enough, as you already have the delegation code, only change the line where you create a SecondViewController object. Rather than creating a new one, you should have a reference to the one that the tab bar will show.
In the viewDidLoad of FirstViewController,
Change
SecondViewController *svc = [[SecondViewController alloc]init];
to
//assuming you have 2 view controllers in the tab bar controller, first being FirstViewController
SecondViewController *svc = [self.tabBarController.viewControllers objectAtIndex:1];
and that should do it
How do you actually get to the second tab? You're creating an instance of it in viewDidLoad, but if you switch tabs, that instance won't be used to show on screen. The system will create another instance which it'll use. You can access this by accessing the tab bar controller's viewcontrollers property and checking for SecondViewController.
EDIT: You could also question your design. I don't know much about your app, but chances are your first tab shouldn't really be the delegate for your second tab. If you want to pass along data, consider using NSNotificationCenter or persistent storage.

Connecting Touch Up Inside event to File's Owner

I’m working through the Multiview Applications chapter of Apress’s Beginning iOS5 development and ran into an issue making a connection from a button on one of the views to File Owner. The general premise of the program is to use a root controller, BIDSwitchViewController to switch between two content views BIDBlueViewController and BIDYellowViewController. Each of the content views has a single button connecting the Touch Up Inside event to the File’s Owner. I had no problem making the connection in BIDBlueViewController, but when I attempt to make this connection in the BIDYellowViewController I’m unable to make a connection between the Touch Up Inside event and the File’s Owner icon.
The instructions in the book state
Drag a Round Rect Button from the library over to the view, using the
guidelines to center the button in the view, both vertically and
horizontally. Double-click the button, and change its title to Press
Me. Next, with the button still selected, switch to the connections
inspector drag from the Touch Up Inside event to the
File's Owner icon, and connect to the blueButtonPressed action method
I’m able to do this without any issues, however when I try complete this instruction for the Yellow View
Drag a Round Rect Button from the library over to the view, using the
guidelines to center the button in the view, both vertically and
horizontally. Double-click the button, and change its title to Press
Me. Next, with the button still selected, switch to the connections
inspector drag from the Touch Up Inside event to the
File's Owner icon, and connect to the yellowButtonPressed action method
The File Owner icon will not let me make the connection, as I drag from the Touch Up Inside event to the File Owner icon File Owner never highlights and I cannot make the connection.
Here is my code
The root controller interface
//
// BIDSwitchViewController.h
// ViewSwitcher
//
//
#import <UIKit/UIKit.h>
#class BIDYellowViewController;
#class BIDBlueViewController;
#interface BIDSwitchViewController : UIViewController
#property (strong, nonatomic) BIDYellowViewController *yellowViewController;
#property (strong, nonatomic) BIDBlueViewController *blueViewController;
- (IBAction)switchViews:(id)sender;
#end
The root controller implementation
//
// BIDSwitchViewController.m
// ViewSwitcher
//
#import "BIDSwitchViewController.h"
#import "BIDYellowViewController.h"
#import "BIDBlueViewController.h"
#implementation BIDSwitchViewController
#synthesize yellowViewController;
#synthesize blueViewController;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
self.blueViewController = [[BIDBlueViewController alloc]
initWithNibName:#"BlueView" bundle:nil];
[self.view insertSubview:self.blueViewController.view atIndex:0];
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (IBAction)switchViews:(id)sender{
if (self.yellowViewController.view.superview == nil){
if (self.yellowViewController == nil) {
self.yellowViewController =
[[BIDYellowViewController alloc] initWithNibName: #"YellowView"
bundle:nil];
}
[blueViewController.view removeFromSuperview];
[self.view insertSubview:self.yellowViewController.view atIndex:0];
} else {
if (self.blueViewController == nil){
self.blueViewController = [[BIDBlueViewController alloc] initWithNibName:#"BlueView"
bundle:nil];
}
[yellowViewController.view removeFromSuperview];
[self.view insertSubview:self.blueViewController.view atIndex: 0];
}
}
- (void) didReceiveMemoryWarning {
// Release the view if it doesn't have a super view
[super didReceiveMemoryWarning];
// Release any cached data, images, etc, that aren't in use
if (self.blueViewController.view.superview == nil){
self.blueViewController = nil;
} else {
self.yellowViewController = nil;
}
}
#end
The blue content view controller interface
//
// BIDSwitchViewController.h
// ViewSwitcher
//
#import <UIKit/UIKit.h>
#class BIDYellowViewController;
#class BIDBlueViewController;
#interface BIDSwitchViewController : UIViewController
#property (strong, nonatomic) BIDYellowViewController *yellowViewController;
#property (strong, nonatomic) BIDBlueViewController *blueViewController;
- (IBAction)switchViews:(id)sender;
#end
The blue content view controller implementation
//
// BIDBlueViewController.m
// ViewSwitcher
//
//
#import "BIDBlueViewController.h"
#interface BIDBlueViewController ()
#end
#implementation BIDBlueViewController
- (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)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
The yellow content view controller interface
//
// BIDYellowViewController.h
// ViewSwitcher
//
#import <UIKit/UIKit.h>
#interface BIDYellowViewController : UIViewController
- (IBAction)yellowButtonPressed;
#end
The yellow content view controller implementation
//
// BIDYellowViewController.m
// ViewSwitcher
//
//
#import "BIDYellowViewController.h"
#interface BIDYellowViewController ()
#end
#implementation BIDYellowViewController
- (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)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end

EXEC_BAD_ACCESS in iOS5 for IBAction

I have written a sample code for button click action in xcode 4.2 for iOS5.
Here is the code
.h
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController
#property(strong,nonatomic) IBOutlet UIButton *button;
-(IBAction)changed;
#end
.m
#import "FirstViewController.h"
#implementation FirstViewController
#synthesize button=_button;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[_button addTarget:self action:#selector(changed) forControlEvents:UIControlEventTouchUpInside];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
-(IBAction)changed
{
NSLog(#"clicked");
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
#end
But when I click the button. I am getting exception. how to solve this issue? the same is working in iOS 4.3
first change this code into this one
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[_button addTarget:self action:#selector(changed) forControlEvents:UIControlEventTouchUpInside];
}
I have found solution for my problem.
The main problem is that, if I create a view controller object locally (i.e., inside any method) and add it as subview then, when you invoke any IBAction, at that time it will raise an exception because, the memory for that viewController is getting deallocated automatically when declared locally.
I guess he needs to add data member for that button as well. I mean code should look like this.
#interface FirstViewController : UIViewController{
IBOutlet *UIButton *button;
}
#property(strong,nonatomic) IBOutlet UIButton *button;
-(IBAction)changed;
#end
and try replacing
#synthesize button = _button;
with
#synthesize button;
in your .m file.
You have the wrong message signature for your changed action. It should be:
- (IBAction)changed:(id)sender
and in the addTarget line of code:
#selector(changed:)
PS: Why are you using _button? I don't think this is related to the problem, but you should be using self.button instead. Accessing instance variables directly should be avoided, especially in this case, where you are allowing the compiler to decide what name the variable should have.
PPS: As mentioned by #InderKumarRathore, you should also be calling [super viewDidLoad] before running your own code.

UIViewController with UIView-inherited class, programmatically

I'm using a library, which is a class that inherits from UIView. How do I programmatically create an UIViewController that uses this class, and not a normal UIView?
The ViewController's .h file looks as follows:
#import <UIKit/UIKit.h>
#import "PLView.h"
#interface HelloPanoramaViewController : UIViewController {
IBOutlet PLView * plView;
}
#property (nonatomic, retain) IBOutlet PLView *plView;
#end
The .m file as follows:
#import "HelloPanoramaViewController.h"
#implementation HelloPanoramaViewController
#synthesize plView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do stuff here...
}
- (void)dealloc
{
[plView release];
[super dealloc];
}
#end
And then I should use a nib to let "plView variable pointing to the view".
But without using Interface Builder, how would I do this programmatically? How could I let this UIViewController create an PLView, instead of an UIView?
your UIViewController will something that looks like
#import "HelloPanoramaViewController.h"
#implementation HelloPanoramaViewController
- (void)loadView
{
self.view = [PLView plview]//or whatever it takes to create the plview.
}
- (void)viewDidLoad
{
//create more objects
}
- (void)viewDidUnload
{
//release unwanted objects that were created viewDidLoad
}
-(void) dealloc
{
// release all
[super dealloc];
}
#end
more info... here
In the place where you create your viewController, also create an instance of your custom view, and then set that view to your controller's view:
HelloPanoramaViewController *controller = [[HelloPanoramaViewController alloc] init];
PLView *view = [[PLView alloc] init];
controller.view = view;