Change the background color of selected TextField - ios

I am creating an app in which I have used user registration.In registration page, I have created many UITextFields.I wants that when a user select any TextField then its background Image is change. I uses the code to do that is:
- (IBAction)touchBegin:(id)sender
{
//UILabel *opt = (UILabel *)[cell viewWithTag:101];
if (_text1.isSelected) {
_text1.background = [UIImage imageNamed:#"big_star_non_rating.png"];
}
else if (_text2.isSelected){
_text2.background = [UIImage imageNamed:#"big_star_non_rating.png"];
}
else if (_text3.isSelected){
_text3.background = [UIImage imageNamed:#"big_star_non_rating.png"];
}
else if (_text4.isSelected){
_text4.background = [UIImage imageNamed:#"big_star_non_rating.png"];
}
else{
}
}
But I am not getting the result according to my need.
What should I use to get correct output?

be sure whether your textfield border style is UITextBorderStyleNone.
yourTextField.borderStyle = UITextBorderStyleNone;
yourTextField.background = [UIImage imageNamed:#"image.png"];

I think that it's better and easier to use UITextFieldDelegate methods like this, for example:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
textField.background = [UIImage imageNamed:#"big_star_non_rating"];
return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
textField.background = [UIImage imageNamed:#"AnImageForNormalStateOrSetNilBackground"];
return YES;
}
Hope it helps.

Related

iOS how do I reset button images?

I have a few buttons that when pressed they change from a plain button to a button with a picture of a tick. The problem I have is that I can't then get a ticked button back to an untucked button when a separate button is pressed. Is this possible at all?
Here are my buttons:
- (IBAction)pickCat:(UIButton *)sender {
[self deselectAllButtons];
((UIButton *)sender).selected = true;
UIImage *btnImage1 = [UIImage imageNamed:#"white - on.png"];
[sender setImage:btnImage1 forState:UIControlStateNormal];
self.catLabel.text = #"WHITE (Hi-Po)";
}
- (IBAction)pickCatb:(UIButton *)sender {
[self deselectAllButtons];
((UIButton *)sender).selected = true;
UIImage *btnImage1 = [UIImage imageNamed:#"red - on.png"];
[sender setImage:btnImage1 forState:UIControlStateNormal];
self.catLabel.text = #"RED (Significant)";
}
- (IBAction)pickCatc:(id)sender {
UIImage *btnImage1 = [UIImage imageNamed:#"yellow - on.png"];
[sender setImage:btnImage1 forState:UIControlStateNormal];
self.catLabel.text = #"YELLOW (Serious)";
}
- (IBAction)pickCatd:(id)sender {
UIImage *btnImage1 = [UIImage imageNamed:#"green - on.png"];
[sender setImage:btnImage1 forState:UIControlStateNormal];
self.catLabel.text = #"GREEN (Important)";
}
- (void)deselectAllButtons
{
// assuming you have a reference to all your buttons
self->Btn1.selected = false;
self->Btn2.selected = false;
}
I like to set a different image for each state: normal and selected. It looks like you're using Interface Builder, and it's really easy to set up your buttons with different images for a normal and a selected state.
Then in your code you can do something like this:
- (IBAction)pickImage:(id)sender {
[self deselectAllButtons];
sender.selected = true;
self.locLabel.text = #"Red";
}
- (IBAction)pickImageb:(id)sender {
[self deselectAllButtons];
sender.selected = true;
self.locLabel.text = #"Red";
}
- (void)deselectAllButtons
{
// assuming you have a reference to all your buttons
self.btn1.selected = false;
self.btn2.selected = false;
...
}
If you want to be able to reset all buttons before changing one to a checked image, you have to have a reference to everything else you want to affect. If you want to get fancy, look into Outlet Collections so you can easily loop through an array of buttons from your IB file and set their selected state to false.
UPDATE:
Here's how your code should probably look:
- (IBAction)pickCat:(UIButton *)sender {
[self deselectAllButtons];
// no need to cast since you changed your method signature.
// the system now expects sender to be a button
// ((UIButton *)sender).selected = true;
sender.selected = true;
// no need to set the image explicitly. if you did things correctly
// in IB, you've already told the button which image to use when
// selected, and which image to use when not (default). when you set
// the line above (sender.selected = true), that will tell the button
// to go use the image that you added to the button's selected state in IB
// UIImage *btnImage1 = [UIImage imageNamed:#"white - on.png"];
// [sender setImage:btnImage1 forState:UIControlStateNormal];
self.catLabel.text = #"WHITE (Hi-Po)";
}
- (IBAction)pickCatb:(UIButton *)sender {
[self deselectAllButtons];
sender.selected = true;
self.catLabel.text = #"RED (Significant)";
}
- (IBAction)pickCatc:(id)sender {
[self deselectAllButtons];
sender.selected = true;
self.catLabel.text = #"YELLOW (Serious)";
}
- (IBAction)pickCatd:(id)sender {
[self deselectAllButtons];
sender.selected = true;
self.catLabel.text = #"GREEN (Important)";
}
- (void)deselectAllButtons
{
// 2 things:
// 1) I'm not sure about self->Btn1. why not self.Btn1?
// 2) it looks like you have 4 buttons (catA, catB, catC, catD). if so, you need to set the selected state for all of them to false
self->Btn1.selected = false;
self->Btn2.selected = false;
self->Btn3.selected = false;
self->Btn4.selected = false;
}

How to Make Case Override Previous Case

I have a number of cases that generate a different image for each case. The problem is, the images seem to stack once they are generated. How can I set each case to override the previous image?
- (void)setTileValue:(NSInteger)tileValue {
_tileValue = tileValue;
self.numberLabel.text = [#(tileValue) stringValue];
UIImageView *backgroundView = [self backgroundView:[#(tileValue) intValue]];
[self.numberLabel addSubview:backgroundView];
self.value = tileValue;
}
- (UIImageView *)backgroundView:(NSUInteger)value {
switch (value) {
case 1:
return [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"background"]]; // light gray
case 2:
return [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"background1"]]; // gray
case 4:
return [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"background2"]]; // gark gray
case 8:
return [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"background3"]]; // red
case 16:
return [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"background4"]]; // orange
default:
return [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"background"]];
}
}
UPDATED CODE: So the program is creating a new image each time with the initWithImage. I set the return to only return the UIImage now. Why doesn't this code fix the issue either?
- (void)setTileValue:(NSInteger)tileValue {
_tileValue = tileValue;
self.numberLabel.text = [#(tileValue) stringValue];
// UIImageView *backgroundView = [self backgroundView:[#(tileValue) intValue]];
UIImageView *backgroundView = [[UIImageView alloc] initWithImage:[self tileBG:[#(tileValue) intValue]]]; [self.numberLabel addSubview:backgroundView];
self.numberLabel.backgroundColor = [self tileColorForValue:[#(tileValue) intValue]];
self.backgroundColor = [self tileColorForValue:[#(tileValue) intValue]];
self.numberLabel.textColor = [self numberColorForValue:[#(tileValue) intValue]];
self.value = tileValue;
}
- (UIColor *)defaultBackgroundColor {
return [UIColor lightGrayColor];
}
- (UIColor *)defaultNumberColor {
return [UIColor colorWithWhite:0.0 alpha:0.0];
}
- (UIImage *)tileBG:(NSUInteger)value {
switch (value) {
case 1:
return [UIImage imageNamed:#"background"]; // light gray
case 2:
return [UIImage imageNamed:#"background1"]; // gray
case 4:
return [UIImage imageNamed:#"background2"]; // gark gray
case 8:
return [UIImage imageNamed:#"background3"]; // red
case 16:
return [UIImage imageNamed:#"background4"]; // red
case 32:
return [UIImage imageNamed:#"background5"]; // red
default:
return [UIImage imageNamed:#"background"]; // red
}
}
You're making a new image view every time and adding it. Eventually this could cause your app to crash due to memory use (tons of image views can be expensice).
Make the image view once, and set its image accordingly (just return an image from your switch statement), or remove the previous image view before adding a new one.
You need to keep a reference to the image view somewhere, ideally a property on whatever class this is. Then, just set its image property. Don't create a new image view here, and don't add any subviews. The image view should be created once, in your init method.
please read my comments above. then modify your setTitleCode to look like this.
- (void)setTileValue:(NSInteger)tileValue
{
_tileValue = tileValue;
self.numberLabel.text = [#(tileValue) stringValue];
UIImageView *backgroundView = (UIImageView *)[self.numberLabel viewWithTag:1000]; // edited code to avoid warning
if (!backgroundView)
{
backgroundView = [[UIImageView alloc] initWithImage:[self tileBG:[#(tileValue) intValue]]];
backgroundView.tag = 1000;
[self.numberLabel addSubview:backgroundView];
}
backgroundView.image = [self tileBG:[#(tileValue) intValue]];
self.numberLabel.backgroundColor = [self tileColorForValue:[#(tileValue) intValue]];
self.backgroundColor = [self tileColorForValue:[#(tileValue) intValue]];
self.numberLabel.textColor = [self numberColorForValue:[#(tileValue) intValue]];
self.value = tileValue;
}
If you mean that after the switch it's creating multiple images, then try using a
break();
But the safe things to do it to create an imageView and init it, then set its image in the switch statement, that way even if it gets placed more than one, it will keep the last reference.

How to set "if there is text in text view"

I have a UIButton that is gray when the user enters a viewController. There is also a UITextView. If the user enters text into the UITextView, then the button should turn red, but if the text view is blank, the the button is gray. If was thinking of doing something like bellow, which does change the color to red if the user enters text, but if the user deletes the text, it stays red instead of going back to gray. Here is the code I am using:
- (void)textViewDidChange:(UITextView *)textView {
if (self.textView.text.length == 0) {
self.navigationItem.rightBarButtonItem.tintColor = [UIColor colorWithRed:193/255.5 green:193/255.0 blue:193/255.0 alpha:1.0];
}else{
self.navigationItem.rightBarButtonItem.tintColor = [UIColor redColor];
}
if (self.titleView.text.length == 0) {
self.navigationItem.rightBarButtonItem.tintColor = [UIColor colorWithRed:193/255.5 green:193/255.0 blue:193/255.0 alpha:1.0];
}else{
self.navigationItem.rightBarButtonItem.tintColor = [UIColor redColor];
}
NSLog(#"Typing has stopped");
}
Use if (self.textView.text.length == 0) instead of checking if the text is null.
For Swift 3:
if (self.textView.text.characters.count == 0)
You could bind the button image to the text view value and then use a value transformer to put in different colored images depending on if there's input.
Code is for OSX but hopefully it's adaptable.
#implementation DBHasTextImageTransformer
- (id)init
{
self = [super init];
if (self) {
// Initialization code here.
}
return self;
}
+ (Class)transformedValueClass
{
return [NSImage class];
}
+ (BOOL)allowsReverseTransformation
{
return NO;
}
- (id)transformedValue:(id)value
{
if ((value == NULL) || [value isEqualToString:#""]) {
return [NSImage imageNamed: #"NoTextImage"];
} else {
return [NSImage imageNamed: #"HasTextImage"];
}
}
#end

Problems with changing the image property of a UIImageView

I have a UIImageView that when a function called I want to change to a different ("active") image and when another called change back to the image before. This is the code:
- (NavButton *)initWithFrame:(CGRect *)fr andImage:(UIImage *)img andActiveImage:(UIImage *)acImg {
NavButton *a = [[NavButton alloc] initWithFrame:*fr];
[a setBackgroundColor:[UIColor clearColor]];
UIImageView *aImg = [[UIImageView alloc] initWithFrame:CGRectMake(8.5, 8.5, 28, 28)];
aImg.tag = 13;
aImg.image = img;
self.orginalImage = img;
self.activeImage = acImg;
[a addSubview:aImg];
return a;
}
- (void)setIsActive:(NSNumber *)isActive {
self.active = isActive;
if ([isActive isEqualToValue:[NSNumber numberWithBool:NO]]) {
[self undoActive];
} else {
[self redoActive];
}
}
- (void)undoActive {
UIImageView *a = (UIImageView *)[self viewWithTag:13];
a.image = self.orginalImage;
}
- (void)redoActive {
UIImageView *a = (UIImageView *)[self viewWithTag:13];
a.image = self.activeImage;
}
When I call [btn setIsActive:[NSNumber numberWithBool:YES]]; or [btn setIsActive:[NSNumber numberWithBool:NO]]; both times it removes the image, but when I don't call either the image stays there. So, how do I make it so when I call them it changes the images of the button to the correct image?
Instead of repeatedly assigning image to imageview, you can assign two images to the image view: one to "image" property and other to "highlightedImage" property. When you want to switch between the images, set the Boolean property "highlighted" as YES or NO.
It will be easier just to do your check as:
if (![isActive boolValue]) {
Then, do some debugging, add some breakpoints and / or logging. Check what values are actually being received. Are the flags set correctly. Are the images set correctly. Is anything nil.

How to get a button's current image using imageForState?

I found a property called imageForState in xcode but am having trouble getting it to do what I want. When a button is pressed, I want to execute a block of code depending on the button's image.
- (IBAction)favButton:(UIButton *)sender {
NSString *currentImage = [sender imageForState:UIControlStateNormal];
if([currentImage isEqualToString:#"already_fav"])
{
// execute code
}
}
However, I am getting the error:
Incompatible pointer types initializing NSString _strong with an expression type of UIImage
Can someone please tell how to get around this?
I am sure that you are not able to compare a string with an image. There is a solution however. All you have to do is set the tag for the image you are wanting to compare, and set the tag of the image you are comparing to.
image1.tag = 1;
image.tag =1;
if(image1.tag == image.tag) {
// execute code
}
that should help, and I hope that it does.
SO, for this exercise, i'll show you. Change the NSString to a UIImage
UIImage *currentImage = [sender imageForState:UIControlStateNormal];
currentImage.tag = 1;
wantedImage.tag = 1;
if(currentImage.tag == wantedImage.tag) {
// do something
}
hopefully this helps you out :)
When you create a UIImage it is just an image and has no string value attached. The name is not carried by the UIImage object.
If it were me (and this isn't the only solution, just another suggestion), i'd create individual UIImage objects (depending on how many we're talking about here) as this should checkable while strings are not.
For example:
UIImage *image1 = [UIImage imageNamed:#"randomName"];
UIImage *image2 = [UIImage imageNamed:#"anotherRandomName"];
[myButton setImage:image2 forState:UIControlStateNormal];
if ([myButton imageForState:UIControlStateNormal] == image1) {
NSLog(#"The button shows image 1 for normal state");
}
else if ([myButton imageForState:UIControlStateNormal] == image2) {
NSLog(#"The button shows image 2 for normal state");
}
else {
NSLog(#"Error!!!!!!! :D");
}
you cant save the Image as a String
try
UIImage *currentImage = [sender imageForState:UIControlStateNormal];
than you can check:
if(currentImage == [UIImage imageNamed:#"already_fav"])
I did this for switching sound/noSound image on button:
- (IBAction)soundAction:(id)sender {
UIImage *sound = [UIImage imageNamed:#"sound"];
UIImage *noSound = [UIImage imageNamed:#"noSound"];
if ([[sender currentImage] isEqual:sound]) {
NSLog(#"IF SOUND IMAGE");
[sender setImage:noSound forState:UIControlStateNormal];
//your code
} else if([[sender currentImage] isEqual:noSound]) {
NSLog(#"IF NO SOUND IMAGE");
[sender setImage:sound forState:UIControlStateNormal];
//your code
}
}

Resources