Why is blackview always null?
#property (strong, nonatomic) UIView *blackView;
[_blackView setFrame:self.view.bounds];
[_blackView setBackgroundColor:[UIColor colorWithWhite:0 alpha:0.8]];
[self.view addSubview:_blackView];
NSLog(#"%#", _blackView); // i get null
I was instantiating it using alloc init before but i need to access this view between methods so i am using it as a property
Try using self.blackview and initialize
self.blackview = [[UIView alloc] initWithFrame:self.view.frame];
Before you do anything to the object(UIView). You must allcate momery for it, and do some initializations. Use alloc and init method. Like:
UIView *blackView = [[UIView alloc] initWithFrame:CGrectMake( , , , )];
I must say, this is something that even the beginners should know.
After you have created a property. Make sure you have synthesized it.
#synthesize blackView;
And then make sure you alloc some memory to it atleast, use
self.blackView = [[UIView alloc]init];
And then you can perform, any function on it, that you want.
#property (strong, nonatomic) UIView *blackView;
Here you have made the decalaration. But that does not mean that you have allocated any memory to it.
In your implementation file you need to allocate memory to it and initialise it as well.
If you are using XCode version 6 and above you dont need to synthesize your property because that is done by Xcode itself.
Otherwise you need to syntesize your property.
#synthesize blackView;
self.blackView = [UIView alloc]initWithFrame:self.view.bounds];
Also if you have a nib file, and there you have alraedy added a UiView and you want it to be your blackView then you have to make an IBoutlet Connection from your nib file to your .h file. in this case you dont need to initialise or allocate memory to your UIView object. That is done by iOS SDk itself.
Related
I have two views, and i'm trying to show text that i getting from first view in UITextField of another . Second view shown by - (source) so methods ViewWillAppear and ViewDidLoad won't work. And viewDidLoad method of second view is runs when app is started.
I'm tried to make method of second class
secondClass.h:
#property (strong, nonatomic) IBOutlet UITextField *itemName;//all hooked up in storyboard
-(void)SetName:(NSString *)name;
secondClass.m:
-(void)SetName:(NSString *)name{
NSLog(#"%#",name);
itemName.text = name;//itemName - textField
}
and use it in first one:
secondViewConroller *secondView = [[secondViewConroller alloc]init];
[secondView SetName:#"Bill"];
NSlog shows "Bill" but textField.text won't change anything.
My guess that app shows UITextField without changes because it shows second view that it gets from viewDidLoad method and i need to update it somehow
My question: What is the best approach to change attributes of UI elements from different classes?
Easiest way:
secondViewConroller.h :
#property NSString * conversationName;
secondViewConroller.m :
#synthesize conversationName;
-(void)SetName:(NSString *)name{
NSLog(#"%#",name);
itemName.text = conversationName
}
On alloc:
secondViewConroller *secondView = [[secondViewConroller alloc]init];
conversationName = #"Set this text";
[secondView SetName:#"Bill"];
I would suggest you to read about Protocols after that.
Easiest way:
in
secondViewConroller.h :
#property (nonatomic, retain) NSString *stringName;
secondViewConroller.m :
#synthesize stringName;
and in viewDidLoad method you write this line
itemName.text = stringName
On alloc:
secondViewConroller *secondView = [[secondViewConroller alloc]init];
secondView.stringName = #"Set this text";
guess there is something wrong with your itemName variable if it appears to get to the nslog.
did you create a referencing outlet in the interface builder for the textfield?
otherwise you can get the right textfield by tag, in IB put for instance tag 1 on the textfield and do in code:
UITextField *tf=(UITextField*)[self.view viewWithTag:1];
tf.text=name;
(replace self.view for the view holding the textfield, if not directly in the main view)
So i found a solution: There's was something wrong with calling method SetName: with parameters that i getting from first UIViewController.
Basically the solution is : create NSObject and put in there value from first UIViewConroller and then use it in second.
This TUTORIAL helped me to resolve the problem.
having a little issue in an ARC environment. Creating an NSObject that adds a view to a parent view - it's basically a 'popup class' that can handle some text and display it.
In a view controller it's instantiated..
CBHintPopup *popup = [[CBHintPopup alloc]init];
[popup showPopupWithText:#"test text" inView:self.view];
And the actual class files..
CBHintPopup.h
#interface CBHintPopup : NSObject {
}
-(void)showPopupWithText:(NSString *)text inView:(UIView *)view;
-(IBAction)closePopup;
#property (nonatomic, strong) UIView *popupView;
#property (nonatomic, strong) UIImageView *blackImageView;
#property (nonatomic, strong) UIButton *closeButton;
#end
CBHintPopup.m
#implementation CBHintPopup
#synthesize popupView,blackImageView, closeButton;
-(void)showPopupWithText:(NSString *)text inView:(UIView *)view {
//CREATE CONTAINER VIEW
self.popupView = [[UIView alloc]initWithFrame:CGRectMake((view.frame.size.width/2)-(225/2),-146,225,146)];
self.popupView.alpha = 0;
self.popupView.backgroundColor = [UIColor clearColor];
//CREATE AND ADD BACKGROUND
UIImageView *popupBackground = [[UIImageView alloc]initWithFrame:CGRectMake(0,0,225,146)];
popupBackground.image = [UIImage imageNamed:#"hintbackground.png"];
[self.popupView addSubview:popupBackground];
//CREATE AND ADD BUTTON
self.closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.closeButton addTarget:self action:#selector(closePopup) forControlEvents:UIControlEventTouchUpInside];
[self.popupView addSubview:self.closeButton];
//CREATE AND ADD LABEL
UILabel *popupTextLabel = [[UILabel alloc]initWithFrame:CGRectMake(22,25,176,93)];
popupTextLabel.text = text;
[self.popupView addSubview:popupTextLabel];
[view addSubview:self.popupView];
}
-(void)closePopup {
NSLog(#"HI");
}
Recieving the following once closePopup is called via pressing the button ('HI' is not printed)..
-[CBHintPopup performSelector:withObject:withObject:]: message sent to deallocated instance 0x246b2fe0
I've tried retaining the button in non-ARC and a load of other methods but simply having no luck. Probably something real simple but i can't nail it. I've removed all the setting up of the labels and images etc to save some space, so ignore alpha's etc.
Any help will be much appreciated, thanks for your time.
Have you implemented the constructor for CBHintPopup,since you have called the constructor
[[CBHintPopup alloc]init];
you have to implement the constructor method like this
in .m file of CBHintPopup
-(id)init{
if(self == [super init]){
// do some initialization here
}
return self;
}
I tried your code and found the crash you mentioned. I found a solution for fixing the crash.
I declared the CBHintPopup *popup; in the viewController's interface. And changed this line
CBHintPopup *popup = [[CBHintPopup alloc]init];
to
popup = [[CBHintPopup alloc]init];
Everything worked fine for me. But I couldn't find the reason behind this. Hope this will help you.
Found a fix for it - instead of CBHintPopup being an NSObject, i simply made it a sub-class of UIView and added self to the parent view (instead of self.popupView). I wouldn't really call this a 'fix' though - more of an alternative method. Surely an NSObject can add a UIView (with a UIBUtton) to a parent view with no problems? Is this a bug?
Make sure you are retaining the object for class CBHintPopup.
I think the crash is coming because object of CBHintPopup deallocates. And hence the action method is not found.
I have the following class:
#interface DiscountDetailViewController : UIViewController {
UILabel * titleLabel;
UILabel * offerLabel;
}
#property (nonatomic, retain) IBOutlet UILabel * titleLabel;
#property (nonatomic, retain) IBOutlet UILabel * offerLabel;
#end
and I tried to do the following in the previous view:
discount = [[DiscountDetailViewController alloc] initWithNibName:#"DiscountDetailViewController" bundle:nil];
discount.titleLabel.text = temp.vendor;
discount.offerLabel.text = temp.description;
[self.navigationController pushViewController:discount animated:YES];
The issue is that, discount.titleLabel.text when printed is always null... I think it's because I define the titleLabel using interface builder.. so is there a way to resolve this?
I've hooked it up with IB as well..
i don't believe the iboutlets get hooked up until the view is on screen for the first time.
you could try setting the label after its displayed, or add another property to store the label text, then set the iboutlet label based on this new property in viewDidLoad in your DiscountDetailViewController.
If your outlets are properly connected then it is only because your titleLabel will not be available until your viewIsLoaded around -(void)viewDidLoad, I recommend you use an NSString property that can set the title label once view is loaded and update it when it is changed (override setter), or if you know your view is about to show try calling view first.
discount = [[DiscountDetailViewController alloc] initWithNibName:#"DiscountDetailViewController" bundle:nil];
//Force view to load, do not really recommend (though for some reason I am showing you how)
[discount view];
discount.titleLabel.text = temp.vendor;
discount.offerLabel.text = temp.description;
[self.navigationController pushViewController:discount animated:YES];
I declared a UIImage and a UIImage View in one viewcontroller like this:
In the .h file:
UIImageView* itemImageView;
UIImage* itemImage;
#property (nonatomic, retain) UIImage* itemImage;
#property (nonatomic, retain) UIImageView* itemImageView;
In the .m file:
#synthesize itemImage, itemImageView;
In another view, I set its value:
UIImage *image = [UIImage imageNamed:#"name1.png"];
imgView.itemImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 82, 166)];
imgView.itemImageView.image = image;
[self.parentViewController.view addSubview:imgView.itemImageView];
[self dismissModalViewControllerAnimated:YES];
Inside this method, the retain count of itemImageView is 2.
But when I go back to the view where I put the property and the synthesize, the retain count is 0 and I cannot access the object.
Any idea whats happening?
Your code here looks ok. (Aside from a memory leak) You're assigning an ImageView with a retain-count +1 to itemImageView, which will increase it to two. You need to call release on your ImageView after setting it to itemImageView:
UIImageView* iv = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 82, 166)];
imgView.itemImageView = iv;
[iv release];
However, this doesn't fix your problem (it will even make it worse..)
Can you show more code? Have you tried stepping through it with the Debugger?
UIImageView* itemImageView;
...
#property (nonatomic, retain) UIImageView* itemImageView;
...
imgView.itemImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 82, 166)];
This causes a double retain since alloc increases the retain counter by 1, and so does the retain setting of the #property.
The general pattern for setting properties is like so:
.h:
SomeClass* someClass;
...
#property (nonatomic, retain) SomeClass* someClass;
.m:
SomeClass* temporarySomeClass = [[SomeClass alloc] init];
self.someClass = temporarySomeClass;
[temporarySomeClass release];
...
Here, we're using a temporary variable to hold the object we alloced, and then doing a release right after.
You'll see that in the Apple example code for sure.
your problem is with this line:
[self.parentViewController.view addSubview:imgView.itemImageView];
this should most likely be edited as such:
[self.parentViewController.view addSubview:self.parentViewController.itemImageView];
this leads to the question of whether imgView is really equivalent to parentViewController.view. if you wanted it to be, then you need to figure out where that got assigned and see where you messed that up. if not, then theres no point in using it for anything but a temporary container to build ur objects in before assigning it.
edit: the memory leak is a separate issue yes, but im not sure how u declared imgView in the method so i left that for you to solve :)
.h file
UIImage *ownImg;
#property (nonatomic, retain) UIImage *ownImg;
.m file
In viewWillAppear method:
UIImage *myImage2 = [UIImage imageNamed:#"thumbnail.png"];
self.ownImg = myImage2;
That is a leak in ownImg, anyone know why it leaking?
BTW, what is the different of using self.ownImg and without the self.
Thanks.
Calling
ownImg = myImage2;
is just an assignment that merely sets the pointers. But calling
self.ownImg = myImage;
will call a #synthesized setter that contains a retain. (I assume you have the #synthesize() for the ownImg.)
Because you're using a setter method that retains you'll have to release it somewhere. Try placing that in the override for the unload method, or if a non-nib class place it in the dealloc.