Subview of UILabel disappears when the text was changed to Unicode string - ios

I am seeing a strange behavior of UILabel and its subview on iOS development.
I want to have a overlay view on the UILabel and want to change only the text of the label.
It works well when the text is digits or alphabets.
However when I changed the text to a Unicode string, the subview disappears.
To reproduce the problem, I created a simple project which just have a label and a button.
The label has a "A" as the initial text.
When the button was tapped, the following method will be called and change the text of UILabel cyclically.
- (void)pushButton:(id)sender
{
if ([[_label text] isEqualToString:#"A"]) {
[_label setText:#"B"];
// add a subview on the label
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
[view setBackgroundColor:[UIColor blueColor]];
[_label addSubview:view];
} else if ([[_label text] isEqualToString:#"B"]) {
[_label setText:#"C"];
} else if ([[_label text] isEqualToString:#"C"]) {
[_label setText:#"D"];
} else if ([[_label text] isEqualToString:#"D"]) {
[_label setText:#"\u2605"];
// after this, the subview disappears
} else {
[_label setText:#"A"];
// after this, the subview appears again
}
}
When I tap the button at the first time, the text is changed to "B" and the subview appears.
Second time and third time, the text is changed to "C" and "D" and the subview is still there.
Howerver the fourth time, the text is changed to "★" and the subview disappears.
Fifth time, the text is changed to "A" and the subview appears again.
In this code, I don't remove the subview and the new subview is created in every cycle.
However in any time the text was changed to "★", all these subviews disappear.
How can I keep the subview being appeared on the UILabel?

UILabel is not intended to have subviews. The solution is to make your blue rectangle a subview of your label's superview. You can position it so that it appears in front of your UILabel.
Thus, where you have this code:
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
[view setBackgroundColor:[UIColor blueColor]];
[_label addSubview:view];
You would instead say this:
UIView *sup = [_label superview];
UIView *view = [UIView new];
[view setBackgroundColor:[UIColor blueColor]];
CGRect r = CGRectMake(0,0,20,20);
r = [sup convertRect:r fromView:_label];
view.frame = r;
[sup addSubview: view];

Related

Adding subviews to an array of UIViews?

I have a scroll view on which I have a main UIView. This main UIView has an array of UIViews in it.
I want to add a test view over this child view
for (NSUInteger i = 0; i<self.maxPage+1; i++) {
CanvasBaseView *view =[[CanvasBaseView alloc]initWithFrame:CGRectMake(0, (self.canvas.height.floatValue+NAPKIN_PADDING)*i, self.canvas.width.floatValue,self.canvas.height.floatValue)];
[view addSubview:[self setDrawView:view]];
}
-(UIView*)setDrawView:(UIView *)main{
UIView *vw =[[UIView alloc]initWithFrame:main.frame];
[vw setBackgroundColor:[UIColor blackColor]];
return vw;
}
But when I do this only the first view has my new black background View. I tried it with Array of 2,6,10 and all of this only the first view is being populated
Even I tried this
UIView *vw = [UIView new];
vw.frame = main.frame;
[vw setBackgroundColor:[UIColor blackColor]];
return vw;
Unfortunately same result.
If I understand correctly you want to add a black overlay to each child view in your loop. In that case you should use the bounds property of the parent view, as child views are relative it's parents view.
Change this line:
UIView *vw =[[UIView alloc]initWithFrame:main.frame];
To this:
UIView *vw =[[UIView alloc]initWithFrame:main.bounds];

Cant Get UIView by Tag

I'm not sure why I cant get the UIView by tag from above screen.
First pink bar is UIView with 55555 tag
First yellow container is UIView with 555552 tag
Label in first yellow container is 555553 tag
So my viewDidLoad as below
- (void)viewDidLoad {
[super viewDidLoad];
[self.navigationItem setTitle:#"Address"];
[self.view setBackgroundColor:[UIColor colorWithHexString:#"#efeff4"]];
UIView *addContainer1 = (UIView *)[self.view viewWithTag:555552];
[addContainer1 setBackgroundColor:[UIColor colorWithHexString:#"#ffffff"]];
UILabel *lblAddress1 = (UILabel *) [self.view viewWithTag:555553];
[lblAddress1 setNumberOfLines:0];
[lblAddress1 sizeToFit];
}
Below code working as expected. Changing whole view to grey color
[self.view setBackgroundColor:[UIColor colorWithHexString:#"#efeff4"]];
Get label in first yellow also working as expected.
UILabel *lblAddress1 = (UILabel *) [self.view viewWithTag:555553];
[lblAddress1 setNumberOfLines:0];
[lblAddress1 sizeToFit];
But to get the UIView with 555552 tag (yellow container) is not working.
UIView *addContainer1 = (UIView *)[self.view viewWithTag:555552];
[addContainer1 setBackgroundColor:[UIColor colorWithHexString:#"#ffffff"]];
What I'm missing here?

How to make popup like keyboard characters in iOS8 custom keyboard?

I want to create popup in iOS8 custom keyboard as shown below image.
Some code are working but can't access outer window of keyboard and occures issue as shown in below image-2
This what i have done in my custom Keyboard its working
//adding pop up when character is tapped
- (void)addPopupToButton:(UIButton *)button
{
CGRect frame,frame1;
if(self.view.frame.size.width == 320)
{
//Keyboard is in Portrait
frame = CGRectMake(0, -25, 28, 43);
frame1=CGRectMake(0, 0, 28, 43);
}
else{
//Keyboard is in Landscape
frame = CGRectMake(3, -25, 35, 43);
frame1=CGRectMake(0, 10, 35, 43);
}
//create pop up view
UIView *popUp=[[UIView alloc]initWithFrame:frame];
//create a label to add to pop up view
UILabel *text = [[UILabel alloc] init];
//set frame for the label and set label title
[text setFrame:frame1];
[text setText:button.titleLabel.text];
text.textAlignment=NSTextAlignmentCenter;
[text setFont:[UIFont boldSystemFontOfSize:30]];
text.backgroundColor=[UIColor whiteColor];
//add label as popup view's subview
[popUp addSubview:text];
//add pop up view as button's subview
[button addSubview:popUp];
}
//remove Pop up view
-(void)endPopUpForButton:(UIButton*)button
{
if ([button subviews].count > 1)
{
[[[button subviews] objectAtIndex:1] removeFromSuperview];
}
}
From the Apple App Extension Programming guide:
Finally, it is not possible to display key artwork above the top edge
of a custom keyboard’s primary view, as the system keyboard does on
iPhone when you tap and hold a key in the top row.
So it seems like you can't add pop-up outside the keyboard frame, so codelgnitor's answer is the best you can do.

My UIView has a UIButton as one of it's subviews but not responding to events in objective-c

Here is my code. It has started to look crowded after an hour or 2 of trying to solve this issue. I've tried setting user interaction enabled to yes, I've tried just using a button alone and not making it the subview of another view.
Right now I have filterBar > filterBarContainer > filterButton.
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.navigationController.navigationBar.userInteractionEnabled = YES;
self.view.userInteractionEnabled = YES;
// Create filter bar with specified dimensions
UIView *filterBar = [[UIView alloc] initWithFrame:CGRectMake(0, 42, self.view.frame.size.width, self.navigationController.navigationBar.frame.size.height)];
[filterBar setUserInteractionEnabled:YES];
// Make it a subview of navigation controller
[[[self navigationController] navigationBar] addSubview:filterBar];
[filterBar setBackgroundColor:[[UIColor whiteColor] colorWithAlphaComponent:0.9f]];
[filterBar setTag:1];
// Reusable vars
// CGFloat filterBarX = filterBar.frame.origin.x;
//CGFloat filterBarY = filterBar.frame.origin.y;
CGFloat filterBarHeight = filterBar.frame.size.height;
CGFloat filterBarWidth = filterBar.frame.size.width;
// Create centre filter button with specified dimensions
UIView *filterButtonContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 2, filterBarWidth / 2 - 30 , filterBarHeight - 10)];
[filterButtonContainer setUserInteractionEnabled:YES];
// Make it a subview of filter bar
[filterBar addSubview:filterButtonContainer];
[filterButtonContainer setBackgroundColor:[UIColor redColor]];
// Centre the button
[filterButtonContainer setCenter:[filterBar convertPoint:filterBar.center fromView:filterBar.superview]];
// Add button to filter button
UIButton *filterButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[filterButton setUserInteractionEnabled: YES];
[filterButton setFrame:CGRectMake(0, 0,40 , 20)];
[filterButton setTitle:#"test" forState:UIControlStateNormal];
[filterButtonContainer addSubview:filterButton];
[filterButton setBackgroundColor:[UIColor yellowColor]];
// self.filterButton = filterButton;
[filterButton addTarget:self action:#selector(filterButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
NSLog(#"dd");
filterButtonContainer.layer.borderColor = [UIColor blackColor].CGColor;
filterButtonContainer.layer.borderWidth = 1;
This is the method I'm trying to trigger.
- (void)filterButtonTapped:(UIButton *)sender
{
NSLog(#"filter button tapped");
UIActionSheet *filterOptions = [[UIActionSheet alloc] initWithTitle:#"Filter Garments"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:#"Recommended", #"What's New", #"Price - High to Low", #"Price - Low to High", nil];
[filterOptions showInView:self.collectionView];
}
Most likely one of your parent views (superviews of your button) have a width or height that places the filter button outside of their area. The button is still displayed (if you don't define that the view should cut off subviews), but elements outside the view's area will not get any touch events. Check your superview's width and height.
You're adding filterBar as a subview of your navigationBar, but you're setting it's y-origin within navigationBar to 42. And then you're setting your filterButtonContainer's y-origin within the filterBar to 2. Assuming navigationBar's height is 44, most of the filterBar and the entirety of your filterButtonContainer and filterButton won't be within their navigationBar superview so the button wouldn't be selectable.
Edit: To make it selectable while keeping the positioning intact, I suggest adding the filter bar to self.view. For example, change:
[[[self navigationController] navigationBar] addSubview:filterBar];
to
[self.view addSubview:filterBar];

Changing the colour of UIView that is created dynamically

I am creating a UIView and its subviews (such as UITextfield, UIButton etc.) dynamically( by reading from JSON )
I am giving tags to all UIView and try to call by tag.
For instance I am trying to change the background colour of a view inside another view.
parent view's tag is 1, subview's is 11.
My sample code is as follows;
UIView *temp = [self.view viewWithTag:1];
if([[temp viewWithTag:11] isKindOfClass:[UIView class]])
{
[((UIView*)[temp viewWithTag:11]) setBackgroundColor:[UIColor blackColor]];
}
But there is no change, no effect.
Could you please help me on solving this.
#define PARENT_VIEW_TAG 1
#define CHILD_VIEW_TAG 11
UIView *parentView = [self.view viewWithTag:PARENT_VIEW_TAG];
for (UIView *vw in [parentView subviews]) {
if(vw.tag == CHILD_VIEW_TAG)
{
[vw setBackgroundColor:[UIColor blackColor]];
}
}

Resources