Hiding all UILabels in NSMutableArray - iphone

I have various UILabels that I would like to hide using a for-loop.
#interface MyViewController : UIViewController {
NSMutableArray * labelArray;
}
#property (nonatomic, retain) IBOutlet UILabel *label1, *label2, *label3;
...
-(void)viewDidLoad {
[super viewDidLoad];
[labelArray initWithObjects:label1,label2,label3,nil];
for(int i=0; i<sizeof(labelArray); i++){
UILabel *label = [labelArray objectAtIndex:i];
label.hidden = !label.hidden;
}
}
When this is executed, the labels are not hidden. They have been "hooked up" in Interface Builder. What am I doing incorrectly? Thanks!

That is not what sizeof is for. That's a compiler construct that tells you how many bytes a value takes up, which has no clue how many elements are in an NSMutableArray at runtime. You want:
for (UILabel *label in labelArray) {
label.hidden = !label.hidden;
}
If that doesn't work, then your array does not contain the objects you believe it does — quite possibly, you've forgotten to actually create the array — simply sending init to nil does not create an object. Either way, you should probably be doing labelArray = [[NSMutableArray alloc] initWithObjects:label1,label2,label3,nil];. alloc and init go together hand-in-glove.

Related

how to use searchController with two arrays

I have two arrays (first names, Last names) in my TableView (cell.textLabel and cell.detailTextLabel)
I want to make a search bar in this TableView.
I have created class with two string.
#interface clientContent : NSObject { }
#property (nonatomic, strong) NSString *clName;
#property (nonatomic, strong) NSString *clLast;
#end
then I have created array in main class (which have Table view) and added my information
like this
for (int i = 0; i < PQntuples(clientQuery); i++)
{
clientContent *cc = [[clientContent alloc] init];
cc.clName = [[NSString alloc] initWithUTF8String:PQgetvalue(clientQuery, i, 0)];
cc.clLast = [[NSString alloc] initWithUTF8String:PQgetvalue(clientQuery, i, 1)];
[allClients addObject:cc];
}
after this I load it into tableView;
clientContent *cc = [allClients objectAtIndex:indexPath.row];
cell.textLabel.text = cc.clName;
cell.detailTextLabel.text = cc.clLast;
}
Then I use
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
How to make it right? I can't understand..
You should override searchDisplayController:shouldReloadTableForSearchString: delegate method of UISearchDisplayController and filter datasource array for searchResultsTableView as you want.
You can apply predicate on your array(array of clientContent object) and change dataSource array. Using predicate you can filter your array on both fields(clName & clLast).
You can get help related to predicates from https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSPredicate_Class/Reference/NSPredicate.html

IBOutlet UIImageView

I got 30 of these codes, with the same implementation:
// .h
#interface ViewController : UIViewController{
IBOutlet UIImageView *circle;
IBOutlet UIImageView *circle2;
}
#property (nonatomic, retain) IBOutlet UIImageView *circle;
#property (nonatomic, retain) IBOutlet UIImageView *circle2;
// .m
#implementation ViewController
#synthesize circle;
#synthesize circle2;
- (void)viewDidLoad
{
circle = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:#"Circle.png"]];
circle2 = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:#"Circle.png"]];
}
And somewhere in my code, Im adding it as a subview.
My problem is,Is there a way to make it shorter, for it to be maintainable.
You can use one IBOutletCollection instead of 30 IBOutlets. You probably want to set the tag on each UIImageView though, so you can still tell them apart.
(This answer assumes you use a nib. Remove the lines where you instantiate the UIImageViews in viewDidLoad if so.)
If you use name like - Circle1.png, Circle2.png, then you can go for for loop for creating this in a loop.
Something like -
for (int i = 0; i < imageCount ; i++ ) {
circle = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:[NSString stringWithFormat: #"Circle%d.png" , i]]];
}
Is there a pattern to where you are putting these views in their superview? If so, you could use a for loop that goes to 30 and programmatically create the views and add them to their superview.
So for example:
for (i = 0; i < 100; i++)
{
UIImageView* circle = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:#"Circle.png"]];
[self.view addSubview:circle];
}
Would add 100 of the image views you would want. Of course you will need to adjust the positions of each of these views in the loop, but this is the general idea.
while creating this viewcontroller pass the frame as a parameter.thats the only thing changing rite??.the image is same and as there are no other properties .. it may work

Storing and opening data in a variable

I'm making an app that calculates certain things.
I need it to be able to take the input from the first textfields, for example 4+4 and save the result in a variable.
In the second text fields there could be 8+8 for example, and the result of that will also be saved into a variable (possibly the same).
Third row of textfields could yield more numbers etc, etc..
In the end there will be a button "Calculate" for example. And that will take the results from first, second, third etc textfields and calculate all of those together and output the end result.
The calculations are of course more advanced than this, but I just need the basic/simple idea of how to do this.
There is no need for saving the data to a file just now, it should just be in the app while the other textfields are being filled.
For 0x8badf00d:
Header.
#interface UnitConverterViewController : UIViewController {
NSMutableArray *calculationsArray;
UITextField *m1Text;
UITextField *m2Text;
}
#property (nonatomic, retain) IBOutlet UITextField *m1Text;
#property (nonatomic, retain) IBOutlet UITextField *m2Text;
#property (nonatomic, retain) IBOutlet NSMutableArray *calculationsArray;
#end
Implementation:
#implementation UnitConverterViewController
#synthesize m1Text, m2Text, calculationsArray;
#synthesize resultTotal = _resultTotal;
-(id)init {
if(self = [super init]){
calculationsArray = [[NSMutableArray alloc] init];
}
}
- (void)compute{
NSString* sumString = [NSString stringWithFormat:#"%d",[m1Text.text intValue]+[m2Text.text intValue]];
[calculationsArray addObject:sumString];
}
-(IBAction)calculate{
int total=0;
for(NSString* sumStr in calculationsArray){
total = total+[sumStr intValue];
}
NSLog(#"Total: %d", total);
[calculationsArray release], calculationsArray = nil;
}
I must be doing something wrong, and I know I need a way to output this, a label and such. But for now I need to know if what I've done so far is correct, and what the best way of outputting it would be.
You should declare the variables to store the results in your header file, these are than accessible from anywhere in your .m file, the same goes for your text fields.
For example:
Calculator.h
#interface Calculator: SuperclassName{
UITextField *_fldOne;
UITextField *_fldTwo;
UITextField *_fldThree;
UITextField *_fldFour;
int resultOne;
int resultTwo;
int _resultTotal;
}
#property(nonatomic, readonly) int resultTotal;
- (void) calculate;
#end
Calculator.m
#implementation Calculator
#synthesize resultTotal = _resultTotal;
- (void) calculate{
resultOne = [_fldOne.text intValue] * [_fldTwo.text intValue];
resultTwo = [_fldThree.text intValue] / [_fldFour.text intValue];
totalResult = resultOne + resultTwo;
}
#end
In this example resultOne and Two, and all the textfields are available throughout your class to work with, the totalResult is set as a readonly property and synthesized to create a getter automaticaly (which returns the value stored in _totalResult because of synchronizing like totalResult = _totalResult) as so it is available to read from outside the class.
As long as it all happens on one screen it should be more than enough, but of course you could make an NSDictionary or NSArray but that seems unnecessary here.
Hope this helps
Save the result to array. Lets say you have NSMutableArray* calculationsArray;//iVar
//initialize calculationsArray in init method
-(id)init
{
if(self = [super init])
{
calculationsArray = [[NSMutableArray alloc] init];
}
}
- (void)compute
{
NSString* sumString = [NSString stringWithFormat:#"%d",[textField1.text intValue]+[textField2.text intValue]);
[calculationsArray addObject:sumString];
}
- (IBAction)calculate
{
int total=0;
for(NSString* sumStr in calculationsArray)
{
total = total+[sumStr intValue];
}
NSLog(#"Total: %d",total);
[calculationsArray release],calculationsArray = nil;
}

Problem With NSArray

i have the following code
#interface TestYourInfoViewController : UIViewController {
IBOutlet UIImageView * questionImage;
NSArray *historyQuestions;
int questionHistoryNo;
}
#property(nonatomic,retain) UIImageView * questionImage;
#property(nonatomic,retain) NSArray *historyQuestions;
#property int questionHistoryNo;
-(IBAction)solution:(id)sender;
#end
- (void)viewDidLoad
{
NSArray* array = [[NSArray alloc]init];
historyQuestions = array;
historyQuestions=UmRandomOrder(49, 1, 0);
questionImage.image = [UIImage imageNamed:[NSString stringWithFormat:#"h%#.jpg",[self.historyQuestions objectAtIndex:0]]];
[array release];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
-(IBAction)solution:(id)sender{
questionHistoryNo= questionHistoryNo+1;
questionImage.image = [UIImage imageNamed:[NSString stringWithFormat:#"h%#.jpg",[self.historyQuestions objectAtIndex:questionHistoryNo]]];
}
when i press the action button it gives me exception in the line [self.historyQuestions objectAtIndex:questionHistoryNo]
i believe the problem is in the nsarray somehow but i don't know what is it.. the exception is
can anyone help me ..
Actually DarkDust has it correct: the source code for UMRandomOrder shows that it properly returns an autorelease NSMutableArray. So, just change the first three lines of your viewDidLoad from:
NSArray* array = [[NSArray alloc]init];
historyQuestions = array;
historyQuestions=UmRandomOrder(49, 1, 0);
to just:
self.historyQuestions=UmRandomOrder(49, 1, 0);
And you'll be fine.
To be specific, there's no need to alloc/init/assign an array you're about to write over, and by using the property setter (self.historyQuestions = ), you'll automatically do a proper retain, as well as avoiding a potential memory leak. That also explains why it works in viewDidLoad (the autoreleased UmRandomOrder is still valid), but not in the action button (it has since been released).

How do i remove the blue highlight when selection occurs in a UIPickerView

when i select a cell in my modified picker view, a blue background colour appears.
all other treads i have seen do not give me a good answer.
anyone has a solution?
pickerView.showsSelectionIndicator = NO;
Just set the UITableViewCell selectionStyle property to UITableViewCellEditingStyleNone
cell.selectionStyle = UITableViewCellEditingStyleNone;
I have add toolbar at the top of picker view and add cutom button as a sub view of toolbar and both picker view and toolbar are add as a subview of Main view so you can handle this.
I've met this one. Let's get a look at it in details. To create your custom picker view, you create your custom UIView class, e.g. :
#interface TimeAroundView : UIView
{
NSString *title;
UIImage *image;
}
#property (nonatomic, retain) NSString *title;
#property (nonatomic, retain) UIImage *image;
#end
Then in your custom picker view controller you create some container, e.g. NSArray, which will get all TimeAroundView objects you want to represent in your picker view. So, for every object you must do
timeAroundViewObject.userInteractionEnabled = NO;
I think -(id)init is the best place for filling that container in, so you get something like this:
- (id)init
{
self = [super init];
if (self) {
// create the data source for this custom picker
NSMutableArray *viewArray = [[NSMutableArray alloc] init];
TimeAroundView *earlyMorningView = [[TimeAroundView alloc] initWithFrame:CGRectZero];
earlyMorningView.title = #"Early Morning";
earlyMorningView.image = [UIImage imageNamed:#"12-6AM.png"];
earlyMorningView.userInteractionEnabled = NO;
[viewArray addObject:earlyMorningView];
[earlyMorningView release];
TimeAroundView *lateMorningView = [[TimeAroundView alloc] initWithFrame:CGRectZero];
lateMorningView.title = #"Late Morning";
lateMorningView.image = [UIImage imageNamed:#"6-12AM.png"];
lateMorningView.userInteractionEnabled = NO;
[viewArray addObject:lateMorningView];
[lateMorningView release];
// .... (more of objects)
self.customPickerArray = viewArray;
[viewArray release];
}
return self;
}
And in your pickerView:viewForRow:forComponent:reusingView: you just return proper element from array.
That works for me.