Loop over an array of UIButtons in Objective-C - objective-c

I have an array of buttons which I want to change some properties in all of them.
The array is like this:
NSArray *buttons = #[_smallButton, _mediumButton, _largeButton, _xlargeButton];
The buttons are outlets:
#property (weak, nonatomic) IBOutlet UIButton *smallButton;
#property (weak, nonatomic) IBOutlet UIButton *mediumButton;
#property (weak, nonatomic) IBOutlet UIButton *largeButton;
#property (weak, nonatomic) IBOutlet UIButton *xlargeButton;
Now I want to change all borderColors and set tag for each in a loop over the array:
for(int i=0; i< buttons.count; i++) {
[buttons[i] layer].borderColor = [UIColor darkGrayColor].CGColor;
[buttons[i] setTag:i];
}
The point is that the setTag works fine and gets applied to all buttons but the borderColor is only changed for the first item, not all of them.
Does anybody know what I've missed?

Try to set a borderWidth and a cornerRadius to all of them, i.e.:
for(int i=0; i< buttons.count; i++) {
[buttons[i] layer].borderColor = [UIColor darkGrayColor].CGColor;
[buttons[i] layer].borderWidth = 1;
[buttons[i] layer].cornerRadius = 4;
[buttons[i] setTag:i];
}

Related

How to access view's subviews without crash while hooking Swift? (Jailbreak)

I have an odd issue where when I change the background of a view, I can no longer see the UILabels that are subviews of that view. I cannot dump the headers for the Calculator app, as it is in Swift, and I don't know what the name of the UILabels are, and FLEXing is no help with that. I want to bring the subviews in front of the background view (there are two subviews), but both of my current methods crash the target app. I was trying to see if I could get it working with just one at the very front though.
My code:
NSMutableArray *labels = [NSMutableArray arrayWithArray:((DisplayView*)self).allSubviews];
if ([labels count] > 0) {
UILabel *mainLabel = labels[0];
[self bringSubviewToFront:mainLabel];
}
((DisplayView*)self).allSubviews = labels;
And I have also tried:
for (UILabel *label in ((DisplayView*)self).allSubviews) {
if ([label isKindOfClass:[UILabel class]]) {
[self bringSubviewToFront:label];
}
I need an alternative method of doing this, a way to bring all of the subviews forward, or someone to tell me what I am doing wrong.
Edit, here's my full code:
#interface DisplayView
#property (nonatomic, copy, readwrite) UIColor *backgroundColor;
#property (nonatomic, assign, readwrite, getter=isHidden) BOOL hidden;
#property (nonatomic, assign, readwrite, getter=isOpaque) BOOL opaque;
#property (nonatomic, assign, readwrite) CGFloat alpha;
#property (nonatomic, copy, readwrite) NSArray *allSubviews;
#property (nonatomic, assign, readwrite) CALayer *layer;
#end
%hook DisplayView
-(void)layoutSubviews {
((DisplayView*)self).opaque = NO;
((DisplayView*)self).backgroundColor = [UIColor blackColor];
((DisplayView*)self).hidden = NO;
((DisplayView*)self).alpha = 1.0;
NSMutableArray *labels = [NSMutableArray arrayWithArray:((DisplayView*)self).layer.sublayers];
if ([labels count] > 0) {
UILabel *mainLabel = labels[0];
[self bringSubviewToFront:mainLabel];
}
}
%end
%ctor {
%init(DisplayView=objc_getClass("Calculator.DisplayView"));
}
Seems like a few possible issues. First, there is no allSubviews on UIView, it probably should be subviews.
NSMutableArray *labels = [NSMutableArray arrayWithArray:((DisplayView*)self).subviews];
if ([labels count] > 0) {
UILabel *mainLabel = labels[0];
(Just want point out that you don't seem to change the array, so why copy it? You can directly access self.subviews)
Second, in the CALayer version, you're casting CALayer to UIView:
NSMutableArray *labels = [NSMutableArray arrayWithArray:((DisplayView*)self).layer.sublayers];
CALayer *mainLabel = labels.firstObject;
if (mainLabel) {
[labels removeObjectAtIndex:0];
[labels addObject:mainLabel];
self.layer.sublayers = labels;
}
Maybe some of this helps

Iterating through labels [duplicate]

This question already has answers here:
Control more than one button using tags
(3 answers)
Closed 8 years ago.
I have a bunch of labels starting from
#property (strong, nonatomic) IBOutlet UILabel *lastNumber0;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber1;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber2;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber3;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber4;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber5;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber6;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber7;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber8;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber9;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber10;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber11;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber12;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber13;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber14;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber15;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber16;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber17;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber18;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber19;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber20;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber21;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber22;
#property (strong, nonatomic) IBOutlet UILabel *lastNumber23;
And these are aimed to be passed through on an iteration basis in a for loop here;
for (int d = 0; d < [lastNumbers count]; d++) {
int value = [[lastNumbers objectAtIndex:d] intValue];
if ([red containsObject:[NSNumber numberWithInteger:value]])
{
self.lastNumber0.text = [NSString stringWithFormat:#"%i", value];
self.lastNumber0.textAlignment = NSTextAlignmentLeft;
self.lastNumber0.textColor = [UIColor redColor];
}
if ([black containsObject:[NSNumber numberWithInteger:value]])
{
self.lastNumber0.text = [NSString stringWithFormat:#"%i", value];
self.lastNumber0.textAlignment = NSTextAlignmentRight;
self.lastNumber0.textColor = [UIColor blackColor];
}
if ([green containsObject:[NSNumber numberWithInteger:value]])
{
self.lastNumber0.text = [NSString stringWithFormat:#"%i", value];
self.lastNumber0.textAlignment = NSTextAlignmentCenter;
self.lastNumber0.textColor = [UIColor greenColor];
}
}
}
Hopefully this makes sense, where self.lastNumber0.text would be replaced with a programtical self.lastNumber[d].text <-- and I know that will not work, but that's what I'm trying to achieve, I tried this
NSString *labelName = [NSString stringWithFormat:#"lastNumber%i", d];
But cannot figure out how to do self.labelName.text = blah...
Thanks for reading and if you need any more information just ask. Thanks!
ANSWER
int yInc = 310;
for (int i = 0; i < 32; i++) {
label[i] = [[UILabel alloc] initWithFrame:CGRectMake(460, yInc, 100, 10)];
label[i].font = [UIFont boldSystemFontOfSize:11];
label[i].backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.3];
[self.view addSubview:label[i]];
yInc = yInc - 10;
}
for (int d = 0; d < 32; d++) {
int value = [[lastNumbers objectAtIndex:d] intValue];
if ([red containsObject:[NSNumber numberWithInteger:value]])
{
label[d].text = [NSString stringWithFormat:#"%i", value];
label[d].textAlignment = NSTextAlignmentLeft;
label[d].textColor = [UIColor redColor];
}
if ([black containsObject:[NSNumber numberWithInteger:value]])
{
label[d].text = [NSString stringWithFormat:#"%i", value];
label[d].textAlignment = NSTextAlignmentRight;
label[d].textColor = [UIColor blackColor];
}
if ([green containsObject:[NSNumber numberWithInteger:value]])
{
label[d].text = [NSString stringWithFormat:#"%i", value];
label[d].textAlignment = NSTextAlignmentCenter;
label[d].textColor = [UIColor greenColor];
}
}
}
Instead of making a bunch of IBOutlets to the individual labels, make a single IBOutletCollection to all of them. Now the labels are the elements of an array and you can just cycle through that array.

Add contents of an IBoutletcollection to an array?

I have two IBoutletcollections called numbers and symbols. I want to add the contents of their title in an array such that the first element of the array is from numbers and second from symbols, third from numbers, fourth from symbols and so on.
Is there a way to do it?
EDIT:
//#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray symbols;
//#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *numbers;
-(void)setNumbers:(NSArray *)numbers
{
_numbers=numbers;
for (UIButton button in self.numbers)
{
Number * number = [[Number alloc]init];
[button setTitle:[number randnum] forState:UIControlStateNormal];
}
}
This is the code for setting the title of the outlet collection numbers.
Here you go, assuming your IBOutletCollections contain elements of class UILabel and have the same number of elements:
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *numbers;
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *symbols;
NSMutableArray *result = [[NSMutableArray alloc] initWithCapacity:self.numbers.count+self.symbols.count];
for (int i = 0; i < self.numbers.count+self.symbols.count; i++) {
if (i%2 == 0) {
[result addObject:((UIButton *)self.numbers[i]).titleLabel.text];
}
else{
[result addObject:((UIButton *)self.symbols[i]).titleLabel.text];
}
}
The solution to your problem is to run a loop and in the loop do a modulo calculation with 2 to find out when you have an even or odd position in the result array, and then add the element from the appropriate IBOutletCollection. Is this clear?

Method Definition for "...:" Not Found

My app keeps coming up with a "Semantic Error" and keeps freezing/crashing.Everything seems to be stringed together fine and it launches without problem. TextFields work fine but as soon as I click anything else it fails and forces out. Any recommendations?
h.
#interface ViewController : UIViewController {
IBOutlet UITextField *buy1;
IBOutlet UITextField *sell1;
IBOutlet UILabel *percentage1;
IBOutlet UILabel *profit1;
IBOutlet UITextField *royalty;
IBOutlet UITextField *buy2;
IBOutlet UILabel *sell2;
IBOutlet UITextField *percentage2;
IBOutlet UILabel *profit2;
}
#property (weak, nonatomic) IBOutlet UITextField *buytext1;
#property (weak, nonatomic) IBOutlet UITextField *selltext1;
#property (weak, nonatomic) IBOutlet UILabel *percentage1;
#property (weak, nonatomic) IBOutlet UILabel *profit1;
#property (weak, nonatomic) IBOutlet UITextField *royalty;
#property (weak, nonatomic) IBOutlet UITextField *buytext2;
#property (weak, nonatomic) IBOutlet UILabel *sell2;
#property (weak, nonatomic) IBOutlet UITextField *percentagetext2;
#property (weak, nonatomic) IBOutlet UILabel *profit2;
-(IBAction)Button;
- (IBAction)backgroundTouched:(id)sender;
- (IBAction)textfieldReturn:(id)sender;
#end
m.
#implementation ViewController
//This is where I keep getting the Semantic Error "Incomplete Implementation"
#synthesize buytext1;
#synthesize selltext1;
#synthesize buytext2;
#synthesize percentagetext2;
- (IBAction)backgroundTouched:(id)sender {
[buy1 resignFirstResponder];
[sell1 resignFirstResponder];
[buy2 resignFirstResponder];
[percentage2 resignFirstResponder];
}
- (IBAction)textFieldReturn:(id)sender {
[buy1 resignFirstResponder];
[sell1 resignFirstResponder];
[buy2 resignFirstResponder];
[percentage2 resignFirstResponder];
}
int VarBuy1 = 0;
int VarSell1 = 0;
int VarProfit1 =0;
int VarPercentage1 =0;
int VarRoyalty = 0;
int VarBuy2 = 0;
int VarSell2 = 0;
int VarProfit2 =0;
int VarPercentage2 =0;
-(IBAction)Button{
VarBuy1 = ([buy1.text intValue]);
VarSell1 = ([sell1.text intValue]);
VarProfit1 = (VarSell1 - (VarSell1 * (VarRoyalty / 100)) - VarBuy1);
VarPercentage1 = (VarProfit1 / VarSell1);
VarSell2 = (VarBuy2 / ((100 - VarRoyalty) / 100 - VarPercentage2));
VarProfit2 = (VarSell2 - (VarSell2 * VarRoyalty) - VarBuy2);
profit1.text = [[NSNumber numberWithInt:VarProfit1] stringValue];
percentage1.text = [[NSNumber numberWithInt:VarPercentage1] stringValue];
sell2.text = [[NSNumber numberWithInt:VarSell2] stringValue];
profit2.text = [[NSNumber numberWithInt:VarProfit2] stringValue];
}
#end
In .h
- (IBAction)textfieldReturn:(id)sender;
In .m
- (IBAction)textFieldReturn:(id)sender
Be careful about letter cases. field and Field.
And an IBAction without (id)sender doesn't sound good.

UIScrollVIew is not scrolling

I have a UIScrollVIew. It contains a view with different controls. I added all of them to a view and then add the view to the UIScrollView. The scroll is not activated, and the content is not centered. Here is the code:
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect frame = texto.frame;
frame.size.height = texto.contentSize.height;
texto.frame = frame;
[self configureView];
[self.scrollView addSubview:self.contentView];
self.scrollView.contentSize = self.contentView.bounds.size;
self.contentView.userInteractionEnabled= NO;
self.scrollView.userInteractionEnabled=TRUE;
}
-(void)configureView{
self.texto.text = self.newsDetail.text;
NSData *imageData= [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:self.newsDetail.image_large]];
self.imagen.image = [UIImage imageWithData:imageData];
self.fecha.text = self.newsDetail.datePublish;
self.titulo.text = self.newsDetail.title;
}
Header code:
#interface detailNewsController : UIViewController{
UIScrollView * __weak scrollView;
UIView * __weak contentView;
}
#property (nonatomic, strong) news *newsDetail;
#property ( weak, nonatomic) IBOutlet UIScrollView *scrollView;
#property (weak, nonatomic) IBOutlet UIView * contentView;
#property (strong, nonatomic) IBOutlet UIImageView *imagen;
#property (strong, nonatomic) IBOutlet UILabel *fecha;
#property (strong, nonatomic) IBOutlet UILabel *titulo;
#property (strong, nonatomic) IBOutlet UITextView *texto;
-(void) configureView;
I see that you link your UIScrollView with a code variable. So check in interface builder if you enabled vertical scrolling (or horizontal one if you need it)