Change background color on textview dynamically - ios

i'm having an edit button which is connected to this method. In this method i want to make the textView editable and change the background. The problem is the background do not seem to change. Why is that?
ViewDidLoad
self.aboutText.backgroundColor = [UIColor clearColor];
self.aboutText.delegate = self;
self.aboutText.editable = NO;
method
-(IBAction)editField:(id)sender {
self.aboutText.backgroundColor = [UIColor whiteColor];
self.aboutText.editable = YES;
}

Okay the issue was i only did set the action and not the target.
All i did was set the target to self.
sorry for the inconvenience

Try the following:
//.h file
#interface AddEntryViewController : UIViewController<UITextViewDelegate>{}
//.m file
//viewDidLoad
_aboutText.delegate = self;
//add the following method
-(void) textViewDidBeginEditing:(UITextView *)textView
{
[textView setTextColor: [UIColor blackColor]];
}

Related

Objective c / iOS: How to override custom class's layoutSubviews in viewController

I have created a custom UILabel class and set the default background color.
Here are .h and .m files of my custom class.
#import <UIKit/UIKit.h>
#interface imLabel : UILabel
#end
AND
#import "imLabel.h"
#implementation imLabel
- (void)drawRect:(CGRect)rect {
}
- (void) layoutSubviews {
self.backgroundColor = [UIColor redColor];
}
#end
It works fine, but here is what I need: I want this work only if the backgroundColor is not set in ViewController.
Here is my viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
label = [[imLabel alloc] initWithFrame:CGRectMake(50, 50, 300, 300)];
label.backgroundColor = [UIColor blueColor];
[self.view addSubview:label];
}
You control whether set label's backgroundColor or not in ViewController, so the best way to meet your need that I think is check the label had set backgroundColor or not, if not then set it.
/* Somewhere in your ViewController */
if (!self.label.backgroundColor) {
self.label.backgroundColor = [UIColor redColor];
}
Delete all your other code in imLabel.m, then:-
(instancetype)initWithFrame:(CGRect)aRect { self = [super initWithFrame:aRect]; if (self) { self.backgroundColor = [UIColor redColor]; } return self;}
Thanks to #Meiliang Dong

UITableView cell selection

I've got a UILabel with a background color in a cell. When I select this cell, the cell changes the color (which it should) but it also changes the background of the label. I want the preserve the background color on the UILabel. When I use an image with just a random color in it it is preserved, but isn't there any better way?
Thanks in advance
Code:
_label = [UILabel new];
_label.translatesAutoresizingMaskIntoConstraints = NO;
_label.font = [UIFont systemFontOfSize:10.f];
_label.backgroundColor = HEXCOLOR(0xFFE5E5E5); //Macro just a UIColor
But I use this way to add a different selection color (could have something to do with it)
UIView *selectionColor = [[UIView alloc] init];
selectionColor.backgroundColor = HEXCOLOR(0XFFF1F1F1);
self.selectedBackgroundView = selectionColor;
self.contentView.backgroundColor = [UIColor whiteColor];
Nothing really more to it. Just a simple label added with autolayout to fill with a padding of 5.
Solution:
Create a subclass of UILabel and just not call super
- (instancetype) initWithColor:(UIColor *)color
{
self = [super init];
if (self) {
[super setBackgroundColor:color];
}
return self;
}
- (void) setBackgroundColor:(UIColor *)backgroundColor
{
//do nothing here!
}
The default behavior of UITableView is that when a cell is selected the background color of all the cell's subviews is temporarily removed.
We usually handled this issue by subclassing UILabel, overwrite setBackgroundColor: and simply do not call [super setBackgroundColor:] after we've set our own color.
#interface MyLabel : UILabel
#property(nonatomic) BOOL backgroundColorLocked;
#end
#implementation MyLabel
-(void) setBackgroundColor:(UIColor*)backgroundColor {
if (_backgroundColorLocked) {
return;
}
super.backgroundColor = backgroundColor;
}
#end
Usage:
MyLabel* label = …;
label.backgroundColor = UIColor.redColor;
label.backgroundColorLocked = YES;
As long as backgroundColorLocked is YES no-one, not even UITableView(Cell), can change the label's background color.

Remove UINavigationBarButton SubView

I have the following method which adds a MKNumberBadgeView to the UINavigationBar of a UITableViewController -
-(void)counterBtn{
MKNumberBadgeView *numberBadge = [[MKNumberBadgeView alloc] initWithFrame:CGRectMake(25, -10, 40, 40)];
numberBadge.strokeColor = [UIColor colorWithRed:239.0/255.0 green:117.0/255.0 blue:33/255.0 alpha:0];
numberBadge.fillColor = [UIColor colorWithRed:239.0/255.0 green:117.0/255.0 blue:33/255.0 alpha:1];
numberBadge.shine = NO;
numberBadge.hideWhenZero = YES;
numberBadge.value = _countBtnNo;
NSLog(#"Value of count = %d", _countBtnNo);
[self.navigationController.navigationBar addSubview:numberBadge];
}
All works fine until I want to change the count value - I have the following function to change the value -
- (void)removeBtn{
NSLog(#"ddd");
_countBtnNo = 0;
[self counterBtn];
}
But this does nothing - So i'm guessing I need to remove the subview first before re-adding - though there doesnt seem to be a removeSubview:numberBadge method - so i'm struggling!
Store a reference to your numberBadge in a property:
#property(nonatomic, strong) MKNumberBadgeView *numberBadge;
Then initialize it. To remove it, just call
[_numberBadge removeFromSuperview];
Alternatively you can just update the value of the counter. No need to remove it.
_numberBadge.value = new value;

Intercept UITextField touch

I would like to intercept a touch on a UITextField, for instance when I first load it I give it a #selector() to load a different method instead of the delegate stuff?
This is my attempt:
descriptionText = [[UITextField alloc] initWithFrame:CGRectMake(10.0, 25.0, infoView.frame.size.width - 20, 100.0)];
descriptionText.backgroundColor = [UIColor whiteColor];
descriptionText.textColor = [UIColor blackColor];
descriptionText.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
descriptionText.userInteractionEnabled = YES;
[descriptionText addTarget:self action:#selector(loadInfoView:) forControlEvents:UIControlEventTouchUpInside];
descriptionText.font = [UIFont fontWithName:#"Helvetica" size:15];
// show view
[infoView addSubview:descriptionText];
However when I debug the method:
- (void)loadInfoView
{
NSLog(#"load other view here");
}
Your problem is in the forControlEvents:: try UIControlEventEditingDidBegin
[descriptionText addTarget:self action:#selector(loadInfoView:) UIControlEventEditingDidBegin];
Your #selector(loadInfoView:) is also wrong if you have - (void)loadInfoView
or #selector(loadInfoView:) and - (void)loadInfoView: (id) sender
or #selector(loadInfoView) and - (void)loadInfoView
However, why you don't use the UITextFieldDelegate?
.m
#interface ViewController () <UITextFieldDelegate>
#property (strong, nonatomic) UITextField *descriptionText;
#end
Remember to:
self.descriptionText.delegate = self;
Then:
-(void) textFieldDidBeginEditing:(UITextField *)textField
{
if (textField == self.descriptionText)
{
[self loadInfoView];
}
}
Keyboard:
If you don't want to show the keyboard you need to add a [descriptionText resignFirstResponder];
I'm not sure you can get actions to be called on a text field on touch like you want.
If that doesn't work, why don't you attach a tap gesture recognizer to your text field?

UILabel only shows up when placed in viewDidAppear of viewcontroller

I can't figure out why a UILabel only shows up when I create it from the viewDidAppear within my viewController. Here is my code so far:
Within AppDelegate:
CGRect viewBounds;
viewBounds.origin.x = 0;
viewBounds.origin.y = 0;
viewBounds.size.width = screenBounds.size.height;
viewBounds.size.height = screenBounds.size.width;
view = [[EAGLView alloc] initWithFrame: viewBounds];
overlayView = [[OverlayView alloc] initWithFrame: screenBounds];
overlayViewController = [[OverlayViewController alloc] init];
[overlayViewController setView:overlayView];
[window addSubview:view];
[window addSubview: overlayViewController.view];
[window makeKeyAndVisible];
[view start];
Within overlayViewController: (This function is successfully called, but the UILabel doesn't show up)
-(void)showText
{
NSLog(#"showText()");
textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 300.0f, 300.0f)];
textLabel.textColor = [UIColor whiteColor];
textLabel.backgroundColor = [UIColor clearColor];
textLabel.textAlignment = UITextAlignmentCenter;
textLabel.font = [UIFont fontWithName:#"Arial" size:30];
textLabel.text = [NSString stringWithFormat:#"TESTING!"];
[self.view addSubview:textLabel];
[self.view bringSubviewToFront:textLabel];
}
Within overlayViewController: (Placing the above code into the viewDidAppear makes it show up from the beginning)
-(void)viewDidAppear:(BOOL)animated
{
textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 300.0f, 300.0f)];
textLabel.textColor = [UIColor whiteColor];
textLabel.backgroundColor = [UIColor clearColor];
textLabel.textAlignment = UITextAlignmentCenter;
textLabel.font = [UIFont fontWithName:#"Arial" size:30];
textLabel.text = [NSString stringWithFormat:#"TESTING!"];
[self.view addSubview:textLabel];
[self.view bringSubviewToFront:textLabel];
[super viewDidAppear:animated];
}
Why would the UILabel not show up from within showText() function when it's called? I verified that the NSLog outputs to the console, yet the UILabel is not on the screen.
To give a little more context, this is an AR application. There is an EAGLView showing the feed of the camera on the screen. As I said, the UILabel, when placed in the viewDidLoad of overlayViewController, shows up the moment the app launches above the camera video feed. When placed inside the showText function, the UILabel doesn't show.
Any help would be appreciated! Thank you!
PS. To give more information, I have tried calling showText() in two ways:
Within my EAGLView.mm (which is where most of the AR functions are handled), I setup a notification as such:
[[NSNotificationCenter defaultCenter] postNotificationName:#"showTextOverlay" object:nil];
Then, within OverlayViewController.m, I placed an observer within ViewDidAppear (since ViewDidLoad doesn't seem to get called, but ViewDidAppear does...)
-(void)viewDidAppear:(BOOL)animated
{
NSLog(#"viewDidAppear");
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(showText)
name:#"showTextOverlay"
object:nil];
[super viewDidAppear:animated];
}
The selector of this observer calls showText(), which is also inside of OverlayViewController.
I next tried a second way:
Within EAGLView.mm, I got the application delegate and controllers directly as such:
ImageTargetsAppDelegate *delegate = (ImageTargetsAppDelegate *)[UIApplication sharedApplication].delegate;
OverlayViewController *controller = delegate.overlayViewController;
[controller showText];
But both ways still did not show any UILabel...
ANSWERED:
I figured this out. It turns out that the way the sample application is written, the updates to UIKit were not being called on the main thread. Therefore, I used the performSelectorOnMainThread when calling my showText...
Thank you everyone for your help!
One thing to think about is that showText ends with these lines:
[self.view addSubview:textLabel];
[self.view bringSubviewToFront:textLabel];
and then the next line is:
[overlayViewController setView:overlayView];
So, what would the value of self.view be in showText if the viewController does even set its view until the next line? You are likely adding a subview to a nil object.
Generally speaking, you should be doing things a little bit differently. The designated initializer for a view controller is initWithNibName:bundle rather than init so it is recommended that you use that.
More importantly, the OverlayViewController should either load its view from a .xib file or implement the loadView method to create its view. If you add the label inside of that method or in one of the methods called after it, like viewDidLoad, you will see the label.

Resources