in the if statement below how could i make piece1's name be dynamic so that it checks for other pieces also which are piece1, piece2, ...piece5.
I would have to make it look like something like [#"piece%d",i] I'm just not sure what the correct way of writing this would be since i'm just starting with iOS.
for (int i = 0; i < 6; i++) {
if(CGRectContainsPoint([piece1 frame], location)){
piece1.center = location;
}
}
Something like this :
for (int i = 0; i < 6; i++) {
// Create a selector to get the piece
NSString *selectorName = [NSString stringWithFormat:#"piece%d", i];
SEL selector = NSSelectorFromString(selectorName);
UIView *peice = [self performSelector:selector];
// Now do your test
if(CGRectContainsPoint([piece frame], location)){
piece1.center = location;
}
}
The key bits are NSSelectorFromString to turn a string into a selector and performSelector: to get the object matching it.
First add tags to your imageView when initializing them
then change your code to this
for (int i = 0; i < 6; i++) {
UIImageView *piece = (UIImageView *)[self.view viewWithTag:i] ;
if(CGRectContainsPoint([piece frame], location)){
piece.center = location;
}
}
make sure your tag matches the value that will be in the loop i values.
Related
I have the array which consists of objects:
ViewController *item1 = [ViewController new];
item1.name = #"Mary";
item1.Description = #"good girl";
ViewController *item2 = [ViewController new];
item2.name = #"Daniel";
item2.Description = #"bad boy";
ComplexArray= [NSArray arrayWithObjects: item1, item2, nil];`
i want to view in labels a name and description if name is equal Mary
for (int i = 0; i < [ComplexArray count]; i++) {
if (item[i].name isEqualString:#"Mary") {
_nameLabel.text= item[i].name;
_DescriptionLabel.text= item[i].Description;
}
}
Please help me
You basically had it. All I did was rename item to ComplexArray added [] around the isEqualToString call and added a break:
for (int i = 0; i < [ComplexArray count]; i++) {
ViewController *item = ComplexArray[i];
if ([item.name isEqualString:#"Mary"]) {
_nameLabel.text= item.name;
_DescriptionLabel.text= item.Description;
break; // Added
}
}
There are other ways, but this approach is fine.
BTW: variables should start, by convention, with a lowercase character.
Your problem is you didn't assign anything in item variable. Just update like this and it will work.
for (int i = 0; i < [ComplexArray count]; i++) {
ViewController *item = [ComplexArray objectAtIndex:i]; // you missed this line.
if ([item.name isEqualToString:#"Mary"]) { //you missed the opening "[" and closing "]"
_nameLabel.text= item.name;
_DescriptionLabel.text= item.Description;
}
}
I want to show my long text in a UILabel. But, My design having small size of frame for that UILabel. So, i want to truncate my long text like this[see below]:
Ex:
UILabel Text: "I want to show my long text in a UILabel"
Recent Result: [Using lineBreakMode:]
I want to s........a UILabel
I want to s.....
I want to s
Expected Result: "I want to...."
[Note: I want truncation after the word which can fit within their label frame.]
I hope that you can sense about my expected result. Sorry for my English!.
I am not sure whether there is API for this. If you are not getting answers. You can use the below logic to achieve This is not optimum logic.
-(NSString *) textThatFits:(NSString *) originalText font:(UIFont *) font
{
NSArray *array = [originalText componentsSeparatedByString:#" "];
NSString *stringThatFits;
for (int i = 0 ; i < [array count]; i++)
{
NSString *tempString = [stringThatFits stringByAppendingFormat:#" %#", array[i]];
CGRect boundingRect = [tempString boundingRectWithSize:CGSizeMake(999, 999)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:font}
context:nil];
if (boundingRect.size.width < self.yourLabel.width) {
return stringThatFits;
}
else
{
stringThatFits = tempString;
}
}
return stringThatFits;
}
According to the OP excepted result and the #Naveen logic, I develop the code which works but with some restriction.
Restriction:
Sometimes, extending that label width by adding 10.0 value.
don't give any spaces at begin and end of label text.
Design:
Controls: A UIButton, UITextField, UILabel
Type your text in the UITextField.
Do Action to display your excepted result in the UILabel.
Code:
-(IBAction)actionDisplayTextWithTruncate:(id)sender{
lblFinalResult.frame=CGRectMake(60, 345, 55, 21);
NSString *strGivenText, *strFuncResult, *stringThatFits;
int spaceCount;
//Custom Truncate Function
strGivenText=txtFldGivenText.text;
arrForGivenText_Words = [strGivenText componentsSeparatedByString:#" "];
stringThatFits=#"";
strFuncResult=#"";
for (int i = 0 ; i < [arrForGivenText_Words count]; i++)
{
/* must follow #" %#" - a space before %# */
NSString *tempString = [stringThatFits stringByAppendingFormat:#" %#", arrForGivenText_Words[i]];
CGRect boundingRect = [tempString boundingRectWithSize:CGSizeMake(999, 999) options:NSStringDrawingTruncatesLastVisibleLine attributes:#{NSFontAttributeName:lblFinalResult.font} context:nil];
if (boundingRect.size.width > lblFinalResult.frame.size.width) //Breakpoint1
{
if(i==0){
[lblFinalResult setText:#"..."];
return;
}
else{
for (int j = 0 ; j < i; j++)
{
strFuncResult = [strFuncResult stringByAppendingFormat:#"%# ",arrForGivenText_Words[j]];
NSLog(#"Present_a1: %#", strFuncResult);
}
strFuncResult = [strFuncResult substringToIndex:strFuncResult.length-(strFuncResult.length>0)];
lblFinalResult.frame= CGRectMake(lblFinalResult.frame.origin.x, lblFinalResult.frame.origin.y, lblFinalResult.frame.size.width+10, lblFinalResult.frame.size.height);
strFuncResult=[strFuncResult stringByAppendingString:#"..."];
[lblFinalResult setText:strFuncResult];
return;
}
}
else{
stringThatFits = tempString;
NSLog(#"Present_a2: %#", stringThatFits);
}
}
[lblFinalResult setText:stringThatFits];
}
I've stored 4 unique numbers inside an NSMutableArray from 1-4. i've done that by using this code:
storeArray = [[NSMutableArray alloc] init];
BOOL record = NO;
int x;
for (int i=1; [storeArray count] < 4; i++) //Loop for generate different random values
{
x = arc4random() % 4;//generating random number
if(i==1)//for first time
{
[storeArray addObject:[NSNumber numberWithInt:x]];
}
else
{
for (int j=0; j<= [storeArray count]-1; j++)
{
if (x ==[[storeArray objectAtIndex:j] intValue])
record = YES;
}
if (record == YES)
{
record = NO;
}
else
{
[storeArray addObject:[NSNumber numberWithInt:x]];
}
}
}
I can then print the numbers out using storeArray[1] and so on.
the problem is i want to print the numbers inside this.
[option1 setTitle:questions[r][storeArray[0]] forState: UIControlStateNormal];
[option2 setTitle:questions[r][storeArray[1]] forState: UIControlStateNormal];
[option3 setTitle:questions[r][storeArray[2]] forState: UIControlStateNormal];
[option4 setTitle:questions[r][storeArray[3]] forState: UIControlStateNormal];
How can i do this?, cause i when i do this i get thread sigbrt error?
The problem is that your algorithm is faulty and when there are collisions because you are trying to keep the numbers unique, you don't record anything so your array might not always be the expected length. Actually there is a 91% chance of this happening in your case so it looks like it happens all the time.
Instead of trying to write your own algorithm, just use the existing classes. Simply use an NSSet to guarantee the uniqueness of the numbers in your array.
NSMutableSet *set = [[NSMutableSet alloc] init];
while(set.count < 4) {
int x = arc4random() % 4;
[set addObject:[NSNumber numberWithInteger:x]];
}
NSArray * storeArray = [set allObjects];
I have NSMutableArray containing UIImageViews and NSArray containing UIImages. The arrays are of equal size. I need to set images from the second array to the first one. It would be very convinient to implement it in loop, something like:
for (int i = 0;i < firstArray.count;i++)
[firstArray objectAtIndex:i].image = [secondArray objectAtIndex:i];
but that doesn't compile. It says "Property "image" not found on object of type "id". Is it possible to implement it in loop somehow?
You need to cast from the id type to a UIImageView before accessing properties on it. Use the following...
for (int i = 0;i < firstArray.count;i++)
((UIImageView *)[firstArray objectAtIndex:i]).image = [secondArray objectAtIndex:i];
Alternatively if adding all of those round brackets makes it harder to read, (personally it draws my eye too much) you can do:
UIImageView *imageView = nil;
for (int i = 0;i < firstArray.count;i++) {
imageView = [firstArray objectAtIndex:i];
imageView.image = [secondArray objectAtIndex:i];
}
OR
for (int i = 0;i < firstArray.count;i++)
[[firstArray objectAtIndex:i] setImage:[secondArray objectAtIndex:i]];
I have this code for creating an array of images to display on a view. Most of the pages in my view will have 20 images (in columns of 5, rows of 4), but i actually have 43 images and when my images array contains the final 3, i get an exception when on the 4th iteration of the inner loop, the array is empty.
- (void)displayImages:(NSMutableArray *)images {
NSMutableArray *keysArray = [[NSMutableArray alloc] initWithCapacity:5];
for (int column = 0; column < 5; column++){
[keysArray addObject:[NSMutableArray arrayWithCapacity:5]];
for (int row = 0; row < 4; row++) {
[[keysArray objectAtIndex:column] addObject:[images objectAtIndex:0]];
[images removeObjectAtIndex:0];
}
}
....
Can i get around this?
Thanks.
EDIT:
Following on from this code, is the code which actually pulls the image from the array. But the same scenario occurs... on the fourth iteration it crashes.
for (int column = 0; column < 5; column++) {
for (int row = 0; row < 4; row++){
UIButton *keyButton = [UIButton buttonWithType:UIButtonTypeCustom];
keyButton.frame = CGRectMake(column*kKeyGap, row*kKeyGap, kKeySize, kKeySize);
[keyButton setImage:[[keysArray objectAtIndex:column] objectAtIndex:row] forState:UIControlStateNormal];
[keyButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:keyButton];
}
}
[keysArray release];
I can't test images at this point as the array is emptied already.
Just check to see if there are objects in that array before you try to do anything with it
- (void)displayImages:(NSMutableArray *)images {
NSMutableArray *keysArray = [[NSMutableArray alloc] initWithCapacity:5];
for (int column = 0; column < 5; column++){
[keysArray addObject:[NSMutableArray arrayWithCapacity:5]];
for (int row = 0; row < 4; row++) {
//test to see if there's an object left in the inner array
if ([images count] > 0) {
[[keysArray objectAtIndex:column] addObject:[images objectAtIndex:0]];
[images removeObjectAtIndex:0];
}
}
}
Try using the actual array sizes instead of constant values in your for loop text expressions. So rather than this:
for (int column = 0; column < 5; column++)
do this:
for (int column = 0; column < [keysArray count]; column++)
The resulting code might look something like this:
for (int column = 0; column < [keysArray count]; column++) {
NSArray *rowArray = [keysArray objectAtIndex:column];
for (int row = 0; row < [rowArray count]; row++) {
UIButton *keyButton = [UIButton buttonWithType:UIButtonTypeCustom];
keyButton.frame = CGRectMake(column*kKeyGap, row*kKeyGap, kKeySize, kKeySize);
[keyButton setImage:[rowArray objectAtIndex:row] forState:UIControlStateNormal];
[keyButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:keyButton];
}
}
By the way, nested message expressions can be cool sometimes, but nesting calls to objectAtIndex: is probably never a good idea.
test the number of object in images