UIImageView.hidden property not functioning? - objective-c

PanelImage is Global allocED and initiated in a method called from ViewDidLoad
PanelImage = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"panel.png"];
[self.view addsubView:PanelImage];
My image comes up properly but
when i try to hide it using
PanelImage.hidden = YES;
it Doesn't hide
i test the property using
if(PanelImage.hidden) but i doesnt pass
i also printed it
NSLog(#"panel is hidden %d",PanelImage.hidden);
it outputs "Panel is hidden 0" even after setting it by
PanelImage.hidden = 1;
please help,atleast tell me some technique to debug it.
there are lots of methods which are using PanelImage.hidden,it used to work before 2days.now only point where PanelImage.hidden works is the custom initialization function(called from ViewDidLoad)
also this is piece of a very big code.
after lots of debugging i came to a point where PanelImage.hidden goes inoperable
PanelImage.hidden = YES;//works till here here
[self GetSymbolAttr];//wont work after this function is called
definition of GetSymbolAttr
-(void)GetSymbolAttr
{
int tmp = 0;
NSArray* PosAndSizeArrForCurrSlot = [[PosAndSizeArr objectAtIndex:SlotId] componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#" "]];
for(NSString* values in PosAndSizeArrForCurrSlot)
PositionAndSize[tmp++] = [values intValue];
}
as you can see nothing is happening in GetSymbolAttr which will make Pattern.hidden go inoperatble

if PanelImage.hidden = YES; is now working than you can do its alpha.set to zero . PanelImage.alpha = 0 ;

try this:
UIImageView *PanelImage = [[UIImageView alloc] initWithImage:[UIImage ...]];
[self.view addsubView:PanelImage];
I didn't find initWithImageNamed method with UIImageView !

Do you set PanelImage.hidden = YES in the same metod, where you're doing UIImageView *PanelImage = [[UIImageView alloc]initWithImageNamed:#"Panel.png"];? Or haven't you class field with the same name PanelImage?

Related

(xcode objective-c) Array - finding a center of a object in an array

I'm pretty nooby when it comes to Xcode but here goes.
I have an NSArray with 5 UIImageView's, I have a script which will pick a random UIImageView, but I need it to then output the center of the image that was chosen.
My code looks like this:
NSMutableArray *Invader = [[NSMutableArray alloc] init];
[Invader addObject:H1];
[Invader addObject:H2];
[Invader addObject:H3];
[Invader addObject:H4];
[Invader addObject:H5];
Then like this to choose where to move a new UIImageView to:
if (FIRE1 == YES){
NSObject *Inv1 = [Invader randomObject]; //randomObject picks a random Invader
InvaderBullet1.hidden = NO;
InvaderBullet1.center = CGPointMake(Inv1.center.x, Inv1.center.y)
}
The error it's giving me is Property 'center' not found on object of type 'NSObject *'
I'm hoping this makes sense to anyone and that anyone can help me.
Thanks
NSObject obviously doesn't have a center property. Though you're not adding NSObjects to your array, you're adding (I assume) UIImageViews. So if you're adding UIImages, you can remove UIImages as well.
if (FIRE1 == YES){
NSObject *Inv1 = [Invader randomObject];
if ([Inv1 isKindOfClass:[UIImageView Class]]) //randomObject picks a random Invader
((UIImageView*)InvaderBullet1).hidden = NO;
((UIImageView*)InvaderBullet1).center = CGPointMake(Inv1.center.x, Inv1.center.y)
}
You simply need to specify the correct type for your variable:
if (FIRE1 == YES){
UIImageView *Inv1 = [Invader randomObject]; //randomObject picks a random Invader
InvaderBullet1.hidden = NO;
InvaderBullet1.center = CGPointMake(Inv1.center.x, Inv1.center.y)
}
This is assuming that your randomObject method (looks like a category method on NSArray) has a return type of id. If its return type is NSObject * then you need to do a cast:
UIImageView *Inv1 = (UIImageView *)[Invader randomObject]; //randomObject picks a random Invader
(Minor note: I recommend to stick to the established naming conventions. In this case: variables usually start with a lower-case character. You're doing other people that need/want to work with your code a favor.)

Programmatically change the state of a UIButton

I've got a pop-up view that loads when a user clicks on a TableView with Core Data elements. On the pop-up view I have a label that represents an int value.
The pop-up view has two butons, one for decreasing the value of the label by 1 and one for increasing it by one. So + and -
What I want to do is to disable the minus button if the label's value is 0. What I've tried is:
-(void)viewDidLayoutSubviews{
NSString *daString = currentVal.text;
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * myNumber = [f numberFromString:daString];
int number = [myNumber intValue];
if (number==0)
minus.enabled = NO;
else
minus.enabled = YES
}
The problem with my code is that the button stays disabled after I increase the label's value, and it's no longer equal to 0.
Any suggestions?
You should keep a reference to minus button e.g.
#property (strong, nonatomic) IBOutlet UIButton *minusButton;
Set it with a value of your minus button, or connect outlet in Interface Builder
in your action handler for plusButton, do something like that
-(IBAction)plusAction:(id)sender {
//Do your business logic
...
self.minusButton.enabled = YES;
}
//In your minusButton action handler
-(IBAction)minusAction:(id)sender {
//Do your business logic
...
NSString *daString = currentVal.text;
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * myNumber = [f numberFromString:daString];
int number = [myNumber intValue];
if (number==0)
self.minusButton.enabled = NO;
else
self.minusButton.enabled = YES
}
It seems like you have things the other way around. I would take a totally different approach:
Keep an instance variable (which we'll call 'count') in this viewController which holds the number. it can be an NSInteger. now add a target (self) to both buttons with a #selector(buttonPressed:). now this is how this selector should look like:
- (void)buttonPressed:(id)sender{
if (sender==plusButton)
self.count++;
if (sender==minusButton)
self.count--;
label.text = [NSString stringWithFormat:#"%d",self.count];
minusButton.enabled = (self.count>0);
}
I would just do this with a UIStepper, instead of the 2 buttons. You can set properties right in your storyboard/IB file that specify the max and min, increments, and a bunch of other useful things too. There are a couple video tutorials posted on YouTube that probably cover everything you'll need to know to use it.
Also, I have noticed one thing that...
If the button in disabled state and you are trying to change the title of normal state, it wont work.
I had to change the state to enabled and then I could manipulate title and set back to disabled.

Book layout NSTextFields -- going back pages?

I have two NSTextfields in a book layout, and I can't figure out a fast way to go back to the previous 'page'. Book size, font size, line size all change, so the string of text for the previous page has to be calculated on the fly. Picture:
The NSTextfields each have one NSTextContainer, and they share a NSLayoutManager and NSTextStorage.
Going forward is easy: I take the character range of the visible text, and then create a substring starting from the next character along.
My going back method is a kludge. I figure out the maximum amount of characters that can be visible at once. I then make a string to that length, with the last character the one I want in the bottom right corner of the book. I then loop: removing characters from the start, checking what is visible each time until the character I want is in the bottom right. This is very, very, slow.
Can anyone suggest a faster way to do what I want to achieve? I had the thought of using scrollRangeToVisible, but I couldn't figure out how to set up a NSScrollView for this layout.
Can anyone help?
Textcontainers are set up like this:
-(void)setupTextViews {
articleString = [[NSAttributedString alloc] init];
articleStringPortion = [[NSAttributedString alloc] init];
bookTextStorage = [[NSTextStorage alloc] init];
bookLayoutManager = [[NSLayoutManager alloc] init];
[[self bookTextStorage] addLayoutManager:bookLayoutManager];
leftColumnRect = NSZeroRect;
rightColumnRect = NSZeroRect;
NSDivideRect(bookRect, &leftColumnRect, &rightColumnRect, NSWidth(bookRect) / 2, NSMinXEdge);
// First column
{
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithContainerSize:leftColumnRect.size];
leftColumnTextView = [[CRMouseOverTextView alloc] initWithFrame:leftColumnRect textContainer:textContainer];
[leftColumnTextView setDrawsBackground:NO];
[leftColumnTextView setEditable:NO];
[leftColumnTextView setup];
[bookView addSubview:leftColumnTextView];
[bookLayoutManager addTextContainer:textContainer];
[textContainer release];
[leftColumnTextView release];
}
// Second column
{
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithContainerSize:rightColumnRect.size];
rightColumnTextView = [[CRMouseOverTextView alloc] initWithFrame:rightColumnRect textContainer:textContainer];
[rightColumnTextView setDrawsBackground:NO];
[rightColumnTextView setEditable:NO];
[rightColumnTextView setup];
[bookView addSubview:rightColumnTextView];
[bookLayoutManager addTextContainer:textContainer];
[textContainer release];
[rightColumnTextView release];
}
}
There's no point posting my awful going backwards code, but I'm using this method I found to figure out what is visible each time:
-(NSRange)getViewableRange:(NSTextView *)tv {
NSLayoutManager *lm = [tv layoutManager];
NSRect visRect = [tv visibleRect];
NSPoint tco = [tv textContainerOrigin];
visRect.origin.x -= tco.x;
visRect.origin.y -= tco.y;
NSRange glyphRange = [lm glyphRangeForBoundingRect:visRect inTextContainer:[tv textContainer]];
NSRange charRange = [lm characterRangeForGlyphRange:glyphRange actualGlyphRange:nil];
return charRange;
}
I'm not sure this is the answer you're looking for, but if it were me, I'd probably just "cache" a bunch of those character ranges, for all the previous pages that have been viewed. You probably wouldn't even have any problem storing them all for a book with a lot of pages. Of course, then you still have to use your kludgy code for when the user re-sizes the text, or whatever. (Either that, or you could re-calculate from some suitable starting point... say the beginning of the book if it's fast enough, or the beginning of a chapter or something. Then you just find the page(range) that contains the text that is already being displayed and show the previous one.)

Using a variable inside a variable objective-C

EDIT: {
No longer need help!
I used tags and a bunch of loops to reference them at anytime.
I never knew you could store so many images in one UIImageView!
}
I have an application that deals with a a lot of images and what i want to do is use an integer inside the variable name so i don't have to write code for each image. Ex:
- (void)addIconClicked {
if (icons < 28) {
icons += 1;
}
if (icons == 2) {
UIImageView * iconImage2 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"icon1.png"]];
//modify image view like setting the frame, setting the title, etc... (not important)
}
else if (icons == 3) {
// iconImage 3 set up
}
this continues all the way up to iconImage26!
so i was wondering if i could use the integer "icons" as part of the variable name so i don't have to run the code 26 different times!!
Ex:
- (void)addIconClicked {
if (icons < 28) {
icons += 1;
}
/*some how insert the "icons" int where (icons) is. Like NSString uses
stringWithFormat ([NSString stringWithFormat:#"%i", icons])*/
UIImageView * iconImage(icons) = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:#"icon%i.png", icons]]];
}
-----edit----- (to clarify what i want)
my problem is that i want to make an unlimited amount of image views but if i use the same variable more than once, it would show up on the view fine, but it would be released and i can't edit it anymore.
Ex:
- (void)addIconClicked {
if (icons < 28) {
icons += 1;
}
NSString * iconName = [NSString stringWithFormat:#"icon%i.png", icons];
//if i ran this 100 times, 100 images would show up, but i can no longer edit any of them except the newest.
iconImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:iconName]];
}
so i need to know how to make an unlimited amount of images that i can still edit individually.
i thought i might be able to use the integer's value inside a variable name when i create it, but i guess i can't:(
so if anyone knows, please explain!!
so to sum it up...
my exact problem is that i want to create an unlimited number of UIImageView's using a different image each time.
You think i could just use 1 variable for all of the images (which would show up) but then i can't edit them at all because they are released.
I just need a way to create an unlimited amount of Global UIImageViews that i can edit and access at any time.
The best way to do this is with an array.
NSMutableArray* allIcons = [NSMutableArray array]; //First, you'll need this empty array.
//Then, when you create your icon...
NSString* iconName = [NSString stringWithFormat:#"icon%lx.png",icons];
UIImageView * newIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:iconName]];
[allIcons addObject:newIcon]; //This adds the icon at the next index, starting at 0.
Then, when you use your icons, instead of icon1, icon2, and so on, use [allIcons objectAtIndex:0], [allIcons objectAtIndex:1], and so on.
This is a pretty common concept--you should consider checking out a few beginning Cocoa tutorials; you might find it in use.
You can use an array for storing UIImageView references. Or you can set their tags and find them later using viewWithTag.
EDIT: Ok I am home now and I can explain:
Use tagging:
UIImageView * anImageView= [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat#"icon%i.png",icons]]];
anImageView.tag=icons;
[parentView addSubview: anImageView];
UIImageView *theOneYouWant = (UIImageView)[parentView viewWithTag:someTag];
or use a c-array of UIImageView pointers to store references if you don't mind scope:
UIImageView * imageViews[28]; // put this into class interface
imageViews[icons]= [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat#"icon%i.png",icons]]];

cocos2d particle effects not appearing

Hi All
Im just having an issue with particle effects not appearing all the time. Im coding using objective c and cocos2d for the iphone.
Below is the code in question.
CCParticleExplosion *emitter;
emitter = [[CCParticleExplosion alloc] initWithTotalParticles:30];
emitter.texture = [[CCTextureCache sharedTextureCache] addImage:#"particle_bubble.png"];
emitter.position = ccp(MidX,MidY);
emitter.life =0.5;
emitter.duration = 0.5;
emitter.speed = 60;
[self addChild:emitter];
emitter.autoRemoveOnFinish = YES;
////////////////////////////////////////////////////
CCParticleMeteor *emitter2;
emitter2 = [[CCParticleMeteor alloc] initWithTotalParticles:150];
emitter2.texture = [[CCTextureCache sharedTextureCache] addImage:#"fire_particle.png"];
emitter2.position = ccp(MidX,MidY);
emitter2.life = 0.5;
emitter2.duration = 2;
emitter2.speed = 60;
id emitMove = [CCMoveTo actionWithDuration:0.5 position:HUD.moonSprite.position ];
[self addChild:emitter2 z:1];
[emitter2 runAction:[CCSequence actions:emitMove, nil]];
emitter2.autoRemoveOnFinish = YES;
This code is within the same function right after each other as shown.
but sometimes the 2nd particle effect is not created and i cant figure out why. the first particle effect is always created no problems so im sure it is getting into the function correctly but sometimes (almost 50%) the 2nd meteor emitter is not displayed. i have tried messing around with z values to make sure it is not hidden behind an other object and it doesnt appear to be the problem. Anyone have any ideas on why this would be happening?
Thanks
G
I suggest using the 71 squared particle designer. http://particledesigner.71squared.com/
Did the trick for me.
Try this:
Define the emitters in a local variable (.h)
Call this before the code above:
if (emitter.parent == self) {
NSLog(#"em1 released");
[emitter release];
}
if (emitter2.parent == self) {
NSLog(#"em2 released");
[emitter2 release];
}
This checks if the emitter is a child and removes it, so you can remove the emitter.autoRemoveOnFinish so your emitter will show every time