How to customize a ui item, and apply that to all viewcontrollers? - ios

I have a UITextField, that I had customized in my firstViewController.
Now I wan't it to have the same behavior on the other ViewControllers.
Is there anyway to import all the properties on a IBOutlet?

simple create your own Customclass and set the property in the constructor.
#interface CustomTextField : UITextField
#end
#implementation CustomTextField
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//Customize here
self.autocapitalizationType = UITextAutocorrectionTypeDefault;
self.text = #"Blub";
....
}
return self;
}
#end
if your create a new Textfield, create the object with your custom class:
CustomTextField *field = [[CustomTextField alloc] initWithFrame: ...];

Why don't you define a base view controller, then derive all of your view controllers from it?
#interface MyBaseCustomViewController : UIViewController
...
#property(...) UITextField* ...
...
#end
#interface MyOtherCustomViewController : MyBaseCustomViewController
...

Yes you could make a subclass of UITextField, this subclass will have the all the custom code that you did in the viewcontroller as a function in your subclass.
For example
- (void) viewDidLoad
{
//UITextField *textField;
//change color, background, size etc..
}
Now create a new class called UICustomTextField that derives from UITextField
in this class create a method:
//in UICustomTextField.m
- (void) doCustomModifications
{
self.stuff = custom stuff;
other custom stuff
etc...
}
Call doCustomModifications in your code
- (void)viewDidLoad
{
[customTextField doCustomModifications];
}

Related

I try to make a member variable's delegate to the class which has this member, but it didn't work

I am a new ios developer, I want to create a new class inherit from NSObject, and it reference a UITextField. it has a property "maxLength" which limits the characters length of the UITextField, then I make the UITextField's delegate as this class"self.textField.delegate=self", and implement the method "textField:shouldChangeCharactersInRange:replacementString:",but when it didn't work, anyone can tell me why? thanks in advance
the code is given below:
#interface TextEditor : NSObject<UITextFieldDelegate>
///limit the characters length in the textfield
#property (nonatomic,assign) NSUInteger maxLength;
///reference a textField
#property (nonatomic,strong) UITextField *textField;
-(id)initWithFrame:(CGRect)frame;
#end
#implementation TextEditor
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (self.textField==textField) {
if (string.length==0) {
return YES;
}
if (textField.text.length-range.length+string.length>_maxLength) {
return NO;
}
}
return YES;
}
-(id)initWithFrame:(CGRect)frame
{
if (self=[super init]) {
_textField=[[UITextField alloc] initWithFrame:frame];
_textField.borderStyle=UITextBorderStyleRoundedRect;
_textField.delegate=self;
}
return self;
}
#end
In the ViewController.m:
- (void)viewDidLoad {
[super viewDidLoad];
TextEditor *te=[[TextEditor alloc] initWithFrame:CGRectMake(50, 270, 200, 50)];
te.maxLength=10;
[self.view addSubview:te.textField];
}
The TextEditor object is declared as local variable inside the viewDidLoad method. This object will be destroyed as long as you leave the viewDidLoad method. The TextEditor object's scope should be maintained until the textField object is destroyed or removed from it's superview. To achieve this, we can make the TextEditor object as instance variable or property.
The code will be changed to
#interface ViewController ()
{
TextEditor *te;
}
- (void)viewDidLoad {
[super viewDidLoad];
te = [[TextEditor alloc] initWithFrame:CGRectMake(50, 270, 200, 50)];
te.maxLength = 10;
[self.view addSubview:te.textField];
}
Like this way your delegate method will not get called. so confirm this in your viewcontroller class and write define delegate method in your viewController.m
No need to do like this.
Second thing if you want custom class for textfield then you should subclass UITextfield not NSObject. This will add UIkit in your class also.
hope this will help :)

Can't set title on UIViewController subclass

I'm having the following problem.
I've created a custom view controller that has a some useful methods that I need.
This is the code in the .h
#interface MYViewController : UIViewController
- (void)method;
- (void)otherMethod;
#end
This is my init method of MYViewController class:
- (instancetype)init
{
self = [super init];
return self;
}
Then when I try to extend that class I can't set the title of the child controller. For example, in "MYOtherController.h"
#interface MYOtherViewController : MYViewController
- (void)childControllerMethod;
#end
And this is the init of MYOtherViewController:
- (instancetype)init
{
self = [super init];
return self;
}
And then, if I instantiate a MYOtherViewController object and try to set the title, it happens nothing. For example:
MYOtherViewController *controller = [[MYOtherViewController] alloc] init];
controller.title = #"Hello";
If I put this in the viewDidLoad of the MYOtherViewController class it logs that title is nil:
- (void)viewDidLoad {
NSLog(#"title: %#", self.title);
[super viewDidLoad];
}
Why can't set the title in this child class?
the title for the viewcontroller hasnt been made yet after the alloc init, you would need to set it after the viewDidLoad (which is when all the UI elements have been initialized), so what you can do is make an #property on the viewcontroller which you set after the alloc init, then in the viewDidLoad, set the title to the value of the #property

Confused about addTarget pointer behavior for addTarget:action:forControlEvents:

I have a UIView subclass with a delegate property. In the init method, I set
self.delegate = nil.
The view also has a button, so in the init method, I also set the target of the button to be self.delegate, which is nil:
[myButton addTarget:self.delegate action:#selector(buttonAction) forControlEvents:UIControlEventTouchUpInside]
In the UIViewController that sets up my UIView subclass, I call a method in the UIView that sets the UIView's self.delegate to the UIViewController. When I click the button, the change in target seems to be reflected.
I am wondering how this ends up working, as my understanding is that addTarget:action:forControlEvents takes an id as the target, and pointers should be pass by value in Obj-C. Thus, I am pretty confused about why the originally nil-valued pointer was updated after the addTarget method was already called.
The right way to do that is declaring a protocol for your view, which will delegate for button's tap action, i.e.
YourView.h
#class YourView;
#protocol YourViewDelegate
#optional
- (void)customView:(YourView *)view didSelectButton:(id)button;
#end
#interface YourView : UIView
//...
#property (weak, nonatomic) id <YourViewDelegate> delegate;
#end
YourView.m
#interface YourView()
#end
#implementation
- (id)init
{
if (self = [super init]) {
//...
[self setup];
}
return self;
}
- (void)awakeFromNib
{
//...
// setup logic when this view created from storyboard
[self setup];
}
- (void)setup
{
[myButton addTarget:self
action:#selector(buttonTapped:)
forControlEvents:UIControlEventTouchUpInside];
}
- (void)buttonTapped:(id)sender
{
if (self.delegate && [self.delegate respondsToSelector:#selector(customVIew:didSelectButton)] {
[self.delegate customView:self didSelectButton:sender];
}
}
#end
Then, in your view controller implement YourViewDelegate category:
#interface YourViewController()
//...
#end
#implementation
- (void)viewDidLoad
{
[super viewDidLoad];
//...
self.yourView.delegate = self;
}
//...
- (void)customView:(YourView *)view didSelectButton:(id)button
{
//do your stuff
}
#end
Objective-C uses Dynamic binding. Method to invoke is determined at runtime instead of at compile time. Which is why it is also referred to as late binding.
Reference link -
https://developer.apple.com/library/ios/documentation/general/conceptual/DevPedia-CocoaCore/DynamicBinding.html
So what will be the delegate and which method is being called is defined at runtime.

ios: delegate doesn't respond

i'm trying to create my first delegate here's what i'm trying to do
at class called PAStepper.h i did this
#class PAStepper;
#protocol StepperDelegate <NSObject>
#required
-(void)didIncrement;
-(void)didDecrement;
#end
#interface PAStepper : UIControl
{
__weak id <StepperDelegate> stepperDelegate;
}
#property (nonatomic, weak) id <StepperDelegate> stepperDelegate;
#end
and synthized the property of course in the .m file
and then putten in the PAStepper.m the following in a method
[self.stepperDelegate didDecrement];
in the controller i want to take the delegate i did this
.h
#interface OCSideCartViewController : UIViewController<StepperDelegate>
.m
- (void)viewDidLoad
{
[super viewDidLoad];
PAStepper *stepper = [[PAStepper alloc]init];
stepper.stepperDelegate = self;
}
-(void)didIncrement{
NSLog(#"inc");
}
-(void)didDecrement{
NSLog(#"dec");
}
knowing that this class is viewController that contain a table that every cell have PAStepper .. all i wanted that the delegate call didIncrement and didDecrement whenever i press the buttons
When you call this method
[self.stepperDelegate didDecrement];
NSLog you stepperDelegate and ensure it is not null. Can you confirm the method which calls your delegate is being called?
you can call this in your pastapper.h file
if ([stepperDelegate respondsToSelector:#selector(didIncrement)])
{
[stepperDelegate performSelector:#selector(didIncrement)];
}
I can´t download the project, so i am guessing..
Is the Stepper in the Interface Builder?
If yes you don´t have to allocate it.
Make an Outlet Connection of the Stepper in the OCSideCartViewController.
Post this in OCSideCartViewController:
- (void)viewWillAppear:(BOOL)animated{
self.stepper.stepperDelegate = self;
[super viewWillAppear:animated];
}
If the Stepper is not an Outlet, you have to add it to your ViewControllers view after setting it´s bounds..

custom protocol doesn't work

In the app I'm working on, I have a UIViewController sublcass and a UIView subclass. in the storyboard the view controller contains the UIview. in the uiview I'm drawing something but I need it to know some values that it should be getting from the view controller. So I created a custom protocol in the view controller .h file:
#protocol SSGraphViewControllerProtocol <NSObject>
- (void)numberOfSemesters:(int)number;
#end
#property (weak, nonatomic) id <SSGraphViewControllerProtocol> delegate;
and in the UIView class I confirmed it as having the protocol above and I implemented its method. However. when I pass a number from the view controller, UIView doesn't receive it. Using NSLog, I figured out that UIView isn't entering - (void)numberOfS:(int)number; am I doing anything wrong? How can I fix it? and is there another way that I can send data from the UIViewController class to the UIView controller?
Here is the full code:
UIViewController.h
#protocol SSGraphViewControllerProtocol <NSObject>
- (void)numberOfSemesters:(int)number;
#end
#interface SSGraphViewController : UIViewController
#property (weak, nonatomic) id <SSGraphViewControllerProtocol> delegate;
#end
UIViewController.m
#implementation SSGraphViewController
- (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.
[self.delegate numberOfSemesters:2];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
UIView.h
#interface SSGraph : UIView <SSGraphViewControllerProtocol>
#end
UIView.m
static int numberOfS = 0;
#implementation SSGraph
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
SSGraphViewController *graph = [[SSGraphViewController alloc] init];
graph.delegate = self;
return self;
}
- (void) numberOfSemesters:(int)number{NSLog(#"YES");
numberOfSemesters= number;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
}
Read This Article, It is best example with Description
http://css.dzone.com/articles/do-not-publishcreating-your
Also read for create Protocol
Following i describe simple Example for How to create protocol
#DetailViewController.h
#import <UIKit/UIKit.h>
#protocol MasterDelegate <NSObject>
-(void) getButtonTitile:(NSString *)btnTitle;
#end
#interface DetailViewController : MasterViewController
#property (nonatomic, assign) id<MasterDelegate> customDelegate;
#DetailViewController.m
if([self.customDelegate respondsToSelector:#selector(getButtonTitile:)])
{
[self.customDelegate getButtonTitile:button.currentTitle];
}
#MasterViewController.m
create obj of DetailViewController
DetailViewController *obj = [[DetailViewController alloc] init];
obj.customDelegate = self;
[self.navigationController pushViewController:reportTypeVC animated:YES];
and add delegate method in MasterViewController.m for get button title.
#pragma mark -
#pragma mark - Custom Delegate Method
-(void) getButtonTitile:(NSString *)btnTitle;
{
NSLog(#"%#", btnTitle);
}
You're creating a view controller instance inside of initWithFrame:, assigning its delegate to be self, and then not keeping a reference to the controller or adding its view into the view hierarchy. This is certainly not what you meant to do. Make the connection in your storyboard instead, by making the delegate property an IBOutlet and connecting them by right clicking on the view controller and dragging from the circle next to the property name onto your view instance.
As an aside I'm not convinced of the utility of using a protocol in this way. If the view needs to know some information to do its job, if should either expose some properties that can be set by the controller, or declare a dataSource protocol and query its dataSource rather than rely on the view controller defining the interface it needs.
// Add an observer to your ViewController for some action in uiview
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveActionNotification:)
name:#"someActionNotification"
object:nil];
// Post Notification and method in your Viewcontroller will be called
[[NSNotificationCenter defaultCenter] postNotificationName:#"someActionNotification" object:self];
// at the end Dont forget to remove Observer.
[[NSNotificationCenter defaultCenter] removeObserver:#"someActionNotification"];

Resources