I have code that creates, adds and tags unbuttons in a uiview which is itself in a uiscrollview. At a certain point I try to change (background color and image) some of the unbuttons with certain tags . The problem is if I choose the first button with tag 0 the for loop bombs out for the image change because either uiscrollview or the uiview do not have that method available. But I am trying to only target the unbuttons within the view (all synched up). If I pick any other buttons it works as expected. I could offset the tag from 0 to one instead but I want to know why my for loop does not work.
for (int i=0; i<[devicesArray count]; i++) {
NSLog(#"red %i", i);
for (UIView *subview in [uiv_ButtonsView subviews]) {
if([subview isKindOfClass:[UIButton class]]) {
int number = [[devicesArray objectAtIndex:i] intValue];
subview.alpha=1.0;
[[subview viewWithTag:number] setBackgroundColor:[UIColor redColor]];
UIButton *btttn = (UIButton *)[subview viewWithTag:number];
[btttn setBackgroundImage:nil forState:UIControlStateNormal];
}
}
}
Thanks - this is now working code:
for (int i=0; i<[devicesArray count]; i++) {
int number = [[devicesArray objectAtIndex:i] intValue];
[[uiv_Quilt viewWithTag:number] setBackgroundColor:[UIColor redColor]];
[[uiv_Quilt viewWithTag:number] setBackgroundImage:nil forState:UIControlStateNormal];
}
for (UIView *subview in [uiv_ButtonsView subviews]) {
subView is a subview of uiv_ButtonsView
if([subview isKindOfClass:[UIButton class]]) {
subView is a UIButton
[[subview viewWithTag:number] setBackgroundColor:[UIColor redColor]];
Hmmm. Now you're getting a subview of the UIButton, with tag 0 - this is the default tag for all views. You're in the private view hierarchy of the UIButton here, we've no idea what this is.
UIButton *btttn = (UIButton *)[subview viewWithTag:number];
Same again - you've told the compiler that you are getting a button back from this call, but you won't be. subView is already a button, buttons don't have other buttons as subviews.
[btttn setBackgroundImage:nil forState:UIControlStateNormal];
So this line of code won't work.
I don't see why you either do all your operations on subView, or use [uiv_ButtonsView viewWithTag:xx] to get your button. In the latter case, you will need to start your tags at 1, since all views have a default tag of 0.
The [subview viewWithTag:number] doesn't make sense to me (your button, subview, presumably doesn't have further subviews). And the iteration through your devicesArray with a nested iteration through the uiv_ButtonsView doesn't makes sense either. If you're using tags, you shouldn't need to iterate through your uiv_ButtonsView's subviews, but rather you could have used [uiv_ButtonsView viewWithTag:number].
Related
Suppose I have a button and a view consisting multiple fields like textfields, textviews etc. There is some input data in the textfield as well as in textview. When I click on button the view gets hide, when i clicked again, it shows up. What I want is, when view reappear, all the input fields should be clear. I can clear the textfields data manually by setting it as empty string (#"") but I want some cleaner solution, which ll clear all the fields of view. I tried doing self.toggleView = nil too, but it doesn't work.
One option for doing this is
- (void)clearTextFieldOrTextViews{
for (UIView *subview in self.subviews)
{
if ([subview isKindOfClass:[UITextField class]]){
textField = (UITextField*)subview;
textField.text = #"";
}else if([subview isKindOfClass:[UITextView class]]){
textView = (UITextview*)subview;
textView.text = #"";
}else if([subview isKindOfClass:[UIButton class]]){
button = (UIButton*)subview;
[button setTitle:#"" forState:UIControlStateNormal];
}
}
}
I'm making a custom view to display a simple star rating system in my app. Each star is a UIButton that has a specific star image-file set as its image. Everything works fine in storyboard but when I run the app on a device each star image is slightly transparent.
When I set the background color of the buttons themselves, they are 100% opaque yet the images are still slightly transparent. Any reason why that same button's image wouldn't be opaque? I just want the stars to always be opaque and not dependent on background.
I just joined SO so I don't have enough reputation to post images yet but here's a link to an image that might explain the issue a bit better: photo
Basic code for the custom UIView:
- (void)layoutSubviews
{
[super layoutSubviews];
self.opaque = YES;
[self drawStars];
}
- (void)drawStars {
float imagePadding = self.padding;
CGFloat starWidth = self.selectedStarImage.size.width;
for (NSInteger counter = 0; counter < self.totalStars; counter++)
{
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(counter * (imagePadding + starWidth), 0, starWidth, starWidth)];
button.opaque = YES;
if (counter >= self.rating) {
[button setImage:self.starImage forState:UIControlStateNormal];
}
else {
[button setImage:self.selectedStarImage forState:UIControlStateNormal];
}
[self addSubview:button];
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
button.tag=counter;
}
}
- (void)updateStars
{
for (UIView *subview in self.subviews) {
[subview removeFromSuperview];
}
[self drawStars];
}
Any help would be much appreciated.
It could happen that the alpha of view on which you are adding the buttons as subviews could be lesser than one.
i think you have to first change the image of star because its background it transparent that is the problem and check the background color of button.
Or
you can create whole transparent image and set proper background color which you want.
These images are not proper. or check it by using another images.
I am using the following to try to access all the UIButtons located inside of a UIScrollView within a UIView. The problem is that the code doesn't seem to locate the buttons and set the border property.
UIView -> UIScrollView -> UIButtons.
I basically want to loop through the buttons and set the border property.
for(UIView *v in [self.viewLightLeakChoices subviews]) {
if([v isKindOfClass:[UIButton class]]) {
v.layer.borderWidth = 0;
}
}
Try this one instead
for (id obj in scrollView.subviews) {
NSString *classStr = NSStringFromClass([obj class]);
if ([classStr isEqualToString:#"UIButton"]) {
UIButton *button = (UIButton*)obj;
button.layer.borderWidth = 2.0;
button.layer.borderColor = [UIColor greenColor].CGColor;
}
}
output
Thanks for the help guys. I ended up doing a bunch of for loops to get down to the UIButtons.
for(UIView *v in [self.viewLightLeakChoices subviews]) {
if([v isKindOfClass:[UIScrollView class]]) {
for(UIView *subView in [v subviews]) {
for(UIButton *btn in [subView subviews]) {
btn.layer.borderWidth = 0;
}
}
}
}
first make sure you are getting subviews of UIScrollView because your structure is
UIView > UIScrollView> UIButton
if you have only 1 scroll view in self.viewLightLeakChoices then set your scrollview tag = 1000 and direct access your scrollview so now you dont need to use loop. and execution will be fast.
UIScrollView *scrlV = [self.viewLightLeakChoices viewWithTag:1000];
for (UIButton *btn in scrlV.subviews)
{
if ([btn isKindOfClass:[UIButton Class]]) {
btn.layer.borderWidth = 1.0;
btn.layer.borderColor = [UIColor whiteColor].CGColor;
}
}
i am unable to get i am expecting you are having scrollview -> uiview ->button
for(UIView *myview in Scrollview.subviews)
{
for ( id mybutton in myview.subviews)
{
if ([mybutton isKindOfClass:[UIButton class]])
{
UIButton *mybtn=(UIButton *)mybutton;
mybtn.layer.borderWidth=0;
}
}
}
You should have create Button class say MyButton extents UIButton, if you do this there is no need to loop through scrollview's subviews.
implement awakeFromNib method and apply border, to apply border refer this SO Post How to create border in UIButton?
I am running this code, because I want to change something on all the buttons within my ViewController when it starts.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
int i = 1;
for (UIButton *btn in self.view.subviews)
{
NSLog(#"Count I - %d ", i);
//NSLog(#"Count I - %d - %#", i, btn.titleLabel.text);
i++;
}
}
The Output it:
2013-11-11 08:15:13.315 testingSingle[7876:a0b] Count I - 1
2013-11-11 08:15:13.317 testingSingle[7876:a0b] Count I - 2
Now this seems strange to me, because it is a new project and nothing has been dragged onto or even changed on the VC in the storyboard or in code - there is nothing to suggest that there 2 UIButtons.
How can I get this message to return 0 if this is the case? My app crashes because of this.
Changing your NSLog to
NSLog(#"%#", [btn class]);
gives the output
_UILayoutGuide
_UILayoutGuide
which shows that there are no buttons, but some other views (perhaps required for Autolayout).
for (UIButton *btn in self.view.subviews)
enumerates all subviews, it does not matter that the loop variable btw is
declared as UIButton *.
To handle only buttons, you have to test the class of each object:
for (UIView *subView in self.view.subviews) {
if ([subView isKindOfClass:[UIButton class]]) {
UIButton *btn = (UIButton *)subView;
// Do something with btn ...
i++;
}
}
I have a UIScrollview in a tab, i added some UIView (NIB) to the UIScrollview. Each UIView has some UISwictch, labels, buttons, etc. How can i get the the label.text inside of the view added to the UIScrollview.
I tried a lot of things but i can access to the content of the UIView added to the UIScrollview.
Check with this,
for (UIView *addedView in [self.scrollView subviews])
{
for (UIView *sub in [addedView subviews])
{
if([sub isKindOfClass:[UILabel class]])
{
UILabel *myLabel = (UILabel *)sub;
NSLog(#"My label :%#",myLabel .text);
}
}
}
Here scrollView is your scroll view. It will print all label's text.
If you need to print any particular label's text. Then add a tag to it and check the tag before printing it, like if(myLabel.tag == 7)
set a unique tag for your label.
eg: label.tag = 10345 (some random number, which is a unique tag)
and you can search for the label in the parentView like this
UILabel *theLabel = (UILabel *)[parentView viewWithTag: 10345];
and then you can do what ever you want with the Label.
Step 1: Add this code in your scrollview
UITapGestureRecognizer *singleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTap:)];
singleTapGestureRecognizer.numberOfTapsRequired = 1;
singleTapGestureRecognizer.enabled = YES;
singleTapGestureRecognizer.cancelsTouchesInView = NO;
[scrollView addGestureRecognizer:singleTapGestureRecognizer];
Step 2: Implement this method
-(void)singleTap:(UITapGestureRecognizer *)gesture
{
// Convert gesture into view for getting subviews
CGPoint point = [gesture locationInView:mainScrollView];
UIView *tappedView = [mainScrollView hitTest:point withEvent:nil];
// Get the subviews of the view
NSArray *subviews = [view tappedView];
// Return if there are no subviews
if ([subviews count] == 0) return;
for (UIView *subview in subviews) {
NSLog(#"%#", subview);
// List the subviews of subview
[self your_method:subview];
}
}