UITextView.text lags when loading text - iphone

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];
}

Related

UITextField shouldChangeCharactersInRange Delegate not working

I am having trouble with a new view I have created, I have a registration view that has a single UITextField on it and a UIButton.
I call this view from another view like so
//otherview.m
- (void)viewDidLoad
{
[super viewDidLoad];
RegistrationAlertViewController *regreg = [[RegistrationAlertViewController alloc] init];
[self.view addSubview:regreg.view];
}
Then I create my regregview like this
//regregView.h
#import <UIKit/UIKit.h>
#interface RegistrationAlertViewController : UIViewController <UITextFieldDelegate> {
// textfields for registration
IBOutlet UITextField *registrationTextFieldA;
}
// textfields for registration
#property (strong, nonatomic) IBOutlet UITextField *registrationTextFieldA;
#end
//regregView.m
#import "RegistrationAlertViewController.h"
#interface RegistrationAlertViewController ()
#end
#implementation RegistrationAlertViewController
#synthesize registrationTextFieldA;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
registrationTextFieldA = [[UITextField alloc] init];
registrationTextFieldA.delegate = self;
[registrationTextFieldA becomeFirstResponder];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if([textField.text length] > 4)
{
//Get next TextField... A simple way to do this:
// UITextField *newTextField = [textField.superview viewWithTag:(textField.tag+1)];
// [newTextField becomeFirstResponder];
return NO;
//remember to set the tags in order
}
return YES; //you probably want to review this...
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if((textField.text.length + string.length) > 4)
{
//Get next TextField... A simple way to do this:
// UITextField *newTextField = [textField.superview viewWithTag:(textField.tag+1)];
// [newTextField becomeFirstResponder];
//remember to set the tags in order
}
return YES; //you probably want to review this...
}
#end
I have the two delegates in my regregView.m
textFieldShouldBeginEditing
shouldChangeCharactersInRange
for some bizarre reason textFieldShouldBeginEditing is entered when the view first loads but then when I start entering characters into registrationTextFieldA shouldChangeCharactersInRange is never being entered for some bizarre reason.
any help figuring out why my delegates are not working properly would be greatly appreciated.
Include UITextFielDelegate category in yourClass.h file and Try this code .
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int length = textField.text.length - range.length + string.length;
if(length > 4)
{
return NO;
}
return YES;
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if([textField.text length] > 4)
{
return NO;
}
return YES; //you probably want to review this...
}
I hope it helps you.
Don't allocate UITextField instance in viewDidLoad method. Replace you code with this :
- (void)viewDidLoad
{
registrationTextFieldA.delegate = self;
[registrationTextFieldA becomeFirstResponder];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
Hope it helps you.
Add UItextField delegate from your xib outlet and declare delegate protocol <uitextfielddelegate> in your .h file.
Definitely it will work fine for You.
Good Luck !!!!
A wild guess here.
The problem is in your otherview.m
- (void)viewDidLoad
{
[super viewDidLoad];
RegistrationAlertViewController *regreg = [[RegistrationAlertViewController alloc] init];
[self.view addSubview:regreg.view];
}
Try making a strong property of RegistrationAlertViewController on top of your otherview.m
#property (nonatomic, strong) RegistrationAlertViewController *regreg;
Then in your view did load, you can do
- (void)viewDidLoad
{
[super viewDidLoad];
RegistrationAlertViewController *regreg = self.regreg;
if (regreg == nil)
{
self.regreg = [[RegistrationAlertViewController alloc] init];
}
[self.view addSubview:regreg.view];
}
Hope that works.. Just seems like a similar problem I ran into before.. Good luck
As you are initializing the view while implementing this file.So set delegate in init method not in viewDidLoad.
#synthesize registrationTextFieldA;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
registrationTextFieldA = [[UITextField alloc] init];
registrationTextFieldA.delegate = self;
[registrationTextFieldA becomeFirstResponder];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}

Passing control between two views in iphone [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Passing model objects from one view controller to another in a navigation stack
I am trying to pass the control between two views in iphone. I have tried this and it works fine when you pass from the first view controller to the second but when i click the second, it blanks out. Why is that so? Any help is appreciated.. Thanks...
Viewcontroller.h
#import <UIKit/UIKit.h>
#import "ViewController2nd.h"
#interface ViewController : UIViewController <SecondViewControllerDelegate>
{
IBOutlet UILabel *lbl;
}
-(IBAction)passdata:(id)sender;
#end
Viewcontroller.m
#import "ViewController.h"
#import "ViewController2nd.h"
#interface ViewController ()
#end
#implementation ViewController
- (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.
}
-(void) changeLabel:(NSString*)str{
lbl.text = #"Hello";
}
-(IBAction)passdata:(id)sender{
ViewController2nd *second = [[ViewController2nd alloc] initWithNibName:nil bundle:nil];
[self presentViewController:second animated:YES completion:^{ }];
}
#end
ViewController2nd.h
#import <UIKit/UIKit.h>
#protocol SecondViewControllerDelegate <NSObject>
#optional
-(void) changeLabel:(NSString*)str;
#end
#interface ViewController2nd : UIViewController{
IBOutlet UIButton *bttn;
}
-(IBAction)bttnclicked;
-(IBAction)back:(id)sender;
#end
ViewController2nd.m
#import "ViewController2nd.h"
#import "ViewController.h"
#interface ViewController2nd ()
#end
#implementation ViewController2nd
- (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 from its nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)bttnclicked{
}
-(IBAction)back:(id)sender{
ViewController *first = [[ViewController alloc] initWithNibName:nil bundle:nil];
[self presentmodalViewController:first animated:YES completion:^{ }];
}
#end
Am i missing something?
If your requirement is to go to the first view change the back: method like:
-(IBAction)back:(id)sender
{
[self dismissViewControllerAnimated:YES completion:NULL];
}
Don't display the parentView as the childView of the chilkdViewController. It also makes memory issues and logical issues.
So if you want to go from the childView to parentView, dismiss the childView and never create the parent object and present it there.

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.

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.

Initialization of controls in custom uiview

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.