Is it possible to force value in property setter? - iphone

What I want is to override UINavigationBar tintColor setter and force default color to it. Bellow is my code (which of course fails). Is there a way to make it work?
#implementation UINavigationBar (UINavigationBarCategory)
- (void)setTintColor:(UIColor *)tint {
self.tintColor = [UIColor greenColor];
}
#end

(I'm using property as a generic term here, in your example it's a stand-in for tintColor)
I don't think you can use the self.property = syntax for assignment inside a setProperty: method. self.property is just an alias for [self setProperty:<value>] and it will recursively call itself.
You'll have to do something like this:
- (void)setProperty:(id)pProperty {
[property autorelease];
property = [pProperty retain];
}
I'm still not 100% sure what you're trying to do will work, but the preceding is a start.

If you want to force a default color of a NavigationBar, why don't you set the tint color in viewDidLoad/viewDidAppear of your view controller??
self.navigationController.navigationBar.tintColor = [UIColor (color you want)];

Related

How to set NSString before calling a method objective c

It might be a simple question yet I could not figure out what I am missing.
In ViewControl.h I declared UIColor
#property (nonatomic, strong) UIColor * myColor;
In ViewControl.m I have a method that do something and return new UIColor
#synthesize myColor = _myColor;
In ViewDidLoad Method
- (void)viewDidLoad
{
myColor = [UIColor RedColor];
}
-(void) ShowColorPopUpView
{
if (!self.wePopoverController)
{
ColorViewController *contentViewController = [[ColorViewController alloc] init];
contentViewController.delegate = self;
self.wePopoverController = [[WEPopoverController alloc] initWithContentViewController:contentViewController];
self.wePopoverController.delegate = self;
self.wePopoverController.passthroughViews = [NSArray arrayWithObject:self.navigationController.navigationBar];
[self.wePopoverController presentPopoverFromRect:self.tvTweetDetails.frame
inView:self.view
permittedArrowDirections:(UIPopoverArrowDirectionUp|UIPopoverArrowDirectionDown)
animated:YES];
} else
{
[self.wePopoverController dismissPopoverAnimated:YES];
self.wePopoverController = nil;
}
}
-(void) colorPopoverControllerDidSelectColor:(NSString *)hexColor
{
_myColor = [GzColors colorFromHex:hexColor];
[self.view setNeedsDisplay];
[self.wePopoverController dismissPopoverAnimated:YES];
self.wePopoverController = nil;
}
- (UIColor *) returnColor
{
return _myColor;
}
My Question starts here: I have two methods to change a textview font and background color
- (IBAction)btnFontColorPopUpMenu:(id)sender
{
[self ShowColorPopUpView];
tvTweetDetails.textColor = [self returnColor];
}
- (IBAction)btnTextViewBackGroundColor:(id)sender
{
[self ShowColorPopUpView];
tvTweetDetails.backgroundColor = [self returnColor];
}
The issue now is when I call the method it return it returns RED and if I call it again it returns the the BlackColor.
How Can I call the method and change the Color to the new one and then return it. I want to get the Black color directly.
I want to execute the method first then return the color but what happens is assign the color before execute the method.
I hope I made it the Question Clear.
Okay, I'll take a whack at this.
I suspect you are doing some kind of presentViewController:... method in your color changer method. That's great, but it has implications. The method you call that in continues to execute during that presentation. That means it may return, etc.
This is where the concept of delegates comes in. You may benefit from restructuring the data flows here a bit.
What I suggest (if I am correct about the presentation of a color picker UI) is that you make the following changes:
Create a #protocol ColorPickerDelegate with one method: -(void) userChoseColor:(UIColor *) color
Add a #property (weak) id<ColorPickerDelegate> delegate to your color picker view controller
make your VC here implement that protocol
Inside the delegate method, set your local property
Implement a custom setter for the local propert, and update the background color whenever the color changes.

Can I reuse colors in Interface Builder?

I've got several yellow buttons created using Inteface Builder. All have the same color. Currently I declare color in each xib. Can I declared it globally and reuse across all xibs?
Not possible in Interface Builder. Do it in code, for example by creating special subclass of the button.
You could use system Color Palette to save the color, but you still need to apply it to all buttons every time you decide to change it. Or you can just use Recently Used Colors in the color chooser, but neither way is enough dynamic.
Yes, you can do this.
At the bottom of the color picker popup in Interface Builder, there's a row of squares you can use to store colors for later use. Drag a color into it from the rectangle where the current color is shown at the top of the color picker to store it, and then just click a stored color later to use it.
I don't believe there is a way to do this entirely in interface builder, unfortunately. However, you can come pretty close with a little bit of code. The best way I've found to be able to change colors throughout the app in one go is to subclass the item that you want to color (UILabel, for instance) to set the color upon initialization:
#interface HuedUILabel : UILabel
#end
#implementation HuedUILabel
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
// Initialization code
self.textColor = [AppConfig primaryColor];
}
return self;
}
#end
Then, set the label to have a custom class in IB:
Now, when you want to change the color of all your UILabels, you can do it by changing your one color def AND you don't have to clutter your code with a bunch of appearance assignments.
Most definitely!
Create a singleton object (you can call it OksanaColor, to be cool)...
... or, if you're really lazy, a read-only UIColor property that you can access from your app delegate.
You can also add a category on UIColor, so you can use it same as when you use UIColor. For example in my App I add a new file called ApplicationColors which contains all my app colors.
#interface UIColor (ApplicationColours)
+(UIColor *)savaColor;
#end
Implementation:
#implementation UIColor (ApplicationColours)
+(UIColor *)savaColor
{
return [UIColor colorWithRed:228.0f/255.0f green:86.0f/255.0f blue:86.0f/255.0f alpha:1.0f];
}
#end
Then to use it in my app, I import the ApplicationColours.h and use the same as any other UIColor. i.e:
label.textColor = [UIColor savaColor];
Here's a very simple implementation of a named colors category for UIColor. With this code in your project, UIColor will remember any colors you want to save, and will let you access your own colors or system colors using +colorWithName:
#interface UIColor (namedColors)
+ (UIColor *) colorWithName:(NSString *) name;
+ (void) setColor:(UIColor *) color forName:(NSString *) name;
#end
static NSMutableDictionary *colorStorage;
#implementation UIColor (namedColors)
+ (NSMutableDictionary *) colorStorage
{
if (!colorStorage)
colorStorage = [[NSMutableDictionary alloc] initWithCapacity:10];
return colorStorage;
}
+ (UIColor *) colorWithName:(NSString *) name
{
UIColor *result =[[self colorStorage] valueForKey:name]; // See if we have a color with this name in the colorStorage.
if (result) return result;
SEL selector = NSSelectorFromString(name); // look for a class method whose selector matches the given name, such as "blueColor" or "clearColor".
if ([self respondsToSelector:selector] && (result = [self performSelector:selector]))
if ([result isKindOfClass:[self class]])
return result;
return nil;
}
+ (void) setColor:(UIColor *) color forName:(NSString *) name
{
[[self colorStorage] setValue:color forKey:name];
}
#end

How to setHighlightedTextColor # NSAttributedString

I have a custom UITableViewCell which uses a NSAttributedString. I want it to change color when the cell is selected. How can I make the NSAttributedString have the same behavior as a UILabel with highlightedTextColor set?
I have tried to change the color at the functions setSelected and setHighlighted of the cell, but it seems that they are called to late (on touchUpInside instead of touchDown)
Thanks in advance!
UILabel subclass solution
#implementation CustomLabelHighlighted
{
NSAttributedString *savedAttributedString;
}
-(void)setHighlighted:(BOOL)highlighted
{
[super setHighlighted:highlighted];
if (!highlighted)
{
[super setAttributedText:savedAttributedString];
return;
}
NSMutableAttributedString *highAttributedString = [savedAttributedString mutableCopy];
NSRange range = NSMakeRange(0, highAttributedString.string.length);
[highAttributedString addAttribute:NSForegroundColorAttributeName value:self.highlightedTextColor range:range];
[super setAttributedText:highAttributedString];
}
- (void)setAttributedText:(NSAttributedString *)attributedText
{
[super setAttributedText:attributedText];
savedAttributedString = attributedText;
}
#end
Typically it's pretty simple to detect selection/highlighting and change colors depending on it. The important methods are:
-(void)setHighlighted:animated:
-(void)setSelected:animated:
note that when overriding you have to use the methods with animated:, otherwise it won't work.
When you want to change only the color, the simplest solution is to let the color to be set on the label and not on the string. Note that the attributed string is still inheriting all the properties of the UILabel.

UITextField isn't working

am new to objective-c programming, so sorry if it's a silly question but i looked thoroughly and couldn't find the error,
p.s: english isn't my first language so programming keywords might be unintentionally used
I've set up a txtfield and defined some of it's properties, such as the keyboard-number pad and stuff, the problem is, when i run it on the simulator, nothing happens, the defult keyboard is called.
i'm just trying to do simple stuff to get it in my head,
in my .h, i have
#interface practiceViewController : UIViewController <UITextFieldDelegate>
{
UITextField *userInput;
}
#property (nonatomic, retain, readwrite) UITextField *userInput;
#end
and in my .m
-(UITextField *)userInput{
if (userInput == nil) {
userInput=[[UITextField alloc]init];
userInput.keyboardType= UIKeyboardTypeNumberPad;
userInput.returnKeyType= UIReturnKeyDone;
userInput.textColor=[ UIColor redColor];
userInput.clearButtonMode= UITextFieldViewModeWhileEditing;
userInput.delegate = self;
}
return userInput;
}
i also tried to make it as an input, but for some reson it's not working
int nInput=[[userInput text] intValue];
whats pissing me off about this is that i did the same in a previous project and the "input worked" only, but now everything isn't.
and my property as i haven't defined anything.
i appreciate your help
I Think you have to set the frame for UITextField like this ...
userInput.frame=CGRectMake(100,100,60,31);
in your -(UITextField *)userInput method, that's y it didn't show ..
Well few things are hazy but ...
You are getting the value of the text field using,
int nInput = [[userInput text] intValue];
If you are not getting the correct value then nInput will be zero. That is because userInput must be nil. You can verify this by logging it by adding NSLog(#"%#", userInput); before the line above.
Whatever value is printed, it looks like your on screen text field is not referenced to by userInput.
Since you're doing the entire thing programmatically, you will have to add your userInput to the view hierarchy by doing this,
[self.view addSubview:self.userInput];
Using the property accessor is important here is important as otherwise userInput would be nil unless you've accessed it using self.userInput earlier.
Although this is tagged iPhone, do you happen to be simulating an iPad? If so, I have run into this. The iPad will not show a number pad keyboard.
userInput= [[UITextField alloc] initWithFrame:CGRectMake(10, 50, 200, 30)]
userInput.keyboardType= UIKeyboardTypeNumberPad;
userInput.returnKeyType= UIReturnKeyDone;
userInput.textColor=[ UIColor redColor];
userInput.clearButtonMode= UITextFieldViewModeWhileEditing;
userInput.delegate = self;
You can just set the frame and add below property(to visible the textfield frame in View otherwise it is not visible in View).
userInput.borderStyle = UITextBorderStyleRoundedRect;
[self.view addSubview:userInput];
I hope it will be helpful to you.

Reload UIViewController and xib

I have an app that has a MyViewController with two subclasses, MyViewControllerMain and MyViewControllerSettings.
In MyViewControllerSettings, I allow the user to change the font, color, etc. How do I instruct MyViewControllerMain to refresh itself so the changes show up?
Thanks,
Tony
Here is what I am doing:
I initialize it in viewDidLoad of my superclass like this:
m_fFontSize = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 28 : 16;
m_MyFont = [UIFont fontWithName:#"Greg's Hand" size:m_fFontSize];
And then in derived settings class, I do this:
NSString * sFont = [fontList objectAtIndex:row];
m_MyFont = [UIFont fontWithName:sFont size:m_fFontSize];
And in my dervied MainView class in viewWillAppear, I do this:
tfName.font = m_MyFont;
It depends - if you have, say, a UILabel, UIButton or the like in your MyViewControllerMain and you change their font / color, they should update themselves (make sure you really set the font, color, etc!).
Otherwise, you can always try [[myViewController view] setNeedsDisplay].
For this you need to redraw the whole view using your settings.
For each & every time, method name:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//Over here just set the font size of all the controllers you are using.
This will definitely solve your problem since this method is called every time before the View Appears.
}