I declared a UIView in the objective-C Class File (Test.m)
#property (nonatomic,strong) UIView *Scene1;
In the StoryBoard, when I am trying to make a reference outlet pointing to the view I set in the objective-C file, Scene 1 is not displayed in the list.
Note: 1. I have already pointed the view to the correct class file.
2. They are all UIView type
Here's the code of the header file (Test.h)
#import "JSMessagesViewController.h"
#interface Test : JSMessagesViewController
#end
Here's the code for the Class File Test.m
#import "Test.h"
#import "MessageData.h"
#interface DeerView () <JSMessagesViewDelegate, JSMessagesViewDataSource, UIImagePickerControllerDelegate, UINavigationControllerDelegate,UIActionSheetDelegate>
#property (strong, nonatomic) NSMutableArray *messageArray;
#property (nonatomic,strong) UIImage *willSendImage;
#property (nonatomic,strong) UIView *Scene1;
#end
#implementation DeerView
#synthesize messageArray, NameInput, Scene1, Scene2, Scene3, Scene4, Name;
...
#end
I am a high school student and a young developer who is still learning more. Hope you can help with my question.
Change your declaration of outlet and mark it as outlet
#property (nonatomic, weak) IBOutlet UIView *Scene1;
And you don't need to declare it as a strong property if you won't remove it from subview.
Related
//MigrationVC.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#interface MigrationVC : UIViewController
#end
//MigrationVC.m
#import "MigrationVC.h"
#interface MigrationVC()
#property (strong, nonatomic) IBOutlet UILabel *label;
#property (strong, nonatomic) IBOutlet UIProgressView *progressView;
#end
#implementation MigrationVC
#end
//CoreData
#import "CoreData.h"
#import "MigrationVC.h"
#interface CoreData()
#property (nonatomic,retain) MigrationVC *migrationVC;
#end
-(void)obsererForKeyPath:(NSString*)keyPath object:(id)object change:(NSDictionary*)change context:(void*)context
{
if([keyPath isEqualToString:#"migrationProgress"])
{
dispatch_async(dispatch_get_main_queue(),^{
float progress=[[change objectForKey:NSKeyValueChangeNewKey] floatValue];
self.migrationVC.progress=progress;
});
}
}
I am trying to learn CoreData and migration right now but this is giving me a quite a headache.
I am trying to access the outlet properties from another classes but always gives red warning (Property 'label' not found on object of type MigrationVC*).
I tried adding a NSString property in .h file which was accessible but when i tried to change the outlet from .m to .h file i couldn't ctrl+drag the view in the .h file.
I never had this problem. I have accessed outlet from .m file many times in the past but it just gives me warning now.
How can i access the properties while outlet in .m file?
I cannot outlet the properties in .h file.
You have to transfer you outlet properties from .m file to .h file (copy and paste). If you want your properties to be public so they have to be declared in header file. If you want them to be private - declare them in implementation file.
//MigrationVC.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#interface MigrationVC : UIViewController
#property (strong, nonatomic) IBOutlet UILabel *label;
#property (strong, nonatomic) IBOutlet UIProgressView *progressView;
#end
//MigrationVC.m
#import "MigrationVC.h"
#interface MigrationVC()
#end
#implementation MigrationVC
#end
As others have pointed out, you need to declare your properties in your header file if you want them to be accessible from other classes. You can, and you should. If you think you can't do that, explain why.
More important, though, is that you should not do what you are trying to do. You should not try to access a view controller's view objects from outside the view controller. That violates the principle of encapsulation, an important principle of object-oriented design. (It means that code outside of your view controller is dependent on the appearance of your view controller. If you later decide to make internal changes to your view controller, you are very likely to break outside code.) In addition to the somewhat abstract "It's bad design" reason for not doing it, it often doesn't work, because at the time to try to modify a view controller's views, they don't exist yet.
Instead, you should create DATA properties (like strings, or floating point progress values) in your view controller and expose those. Then have your view controller's viewWillAppear method install the data into it's views as appropriate. That way the data properties become part of the view controller's public contract without being tied to the internal details of the view controller.
You properties are declared in the private category so they are not visible for other classes. Only properties declared in a header file are visible.
In CoreData.m your MigrationVC is set as retain. I don't know if you can use it since with ARC.
#property (nonatomic,retain) MigrationVC *migrationVC;
It should be
#property (nonatomic,strong) MigrationVC *migrationVC;
And in MigrationVC your outlets should be weak not strong and in .h to be accesible from CoreData.m
At the last line, I got the error: Duplicate interface definition for class "ViewController". I want to do an IBAction. What is the fault? What can I do? Please help me.
//
// ViewController.h
#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>
#interface SimpleEmailViewController : UIViewController <MFMailComposeViewControllerDelegate>
- (IBAction)showEmail:(id)sender;
#end
#interface ViewController : UIViewController <MFMessageComposeViewControllerDelegate> {
}
-(IBAction)sendMessage:(id)sender;
- (IBAction)showEmail:(id)sender;
#property (nonatomic, strong) IBOutlet UIWebView *site ;
- (IBAction)call:(id)sender;
#property (retain, nonatomic) IBOutlet UIButton *myBotton;
#end
#interface ViewController : UIViewController**i**
The problem is exactly what the error states. You defined #interface viewController twice. Change the name of one to something else. As a side note, it is a terrible idea to name something with a name apple has already used. You should change both viewControllers to something else, more descriptive of what it does, like mailViewController or setupViewController. Weird stuff can happen when you use apple defined names.
#interface FSMainiPadViewController : UIViewController
Why don't you just make it simple like this?
// ViewController.h
#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>
#interface ViewController : UIViewController <MFMailComposeViewControllerDelegate, MFMessageComposeViewControllerDelegate>
// Actions
- (IBAction)showEmail:(id)sender;
- (IBAction)sendMessage:(id)sender;
- (IBAction)call:(id)sender;
// Properties
#property (nonatomic, strong) IBOutlet UIWebView *site;
#property (retain, nonatomic) IBOutlet UIButton *myBotton;
#end
I'm developing for iOS 7 but I still have to manually write getters otherwise my properties just don't get initialized. I tried to manually synthesize those properties, even though that shouldn't be needed anymore, but that doesn't do it.
In my view controller below, I use the property motionTracker, which never gets initialized. I have the same issue with all my projects, so I know it's a misunderstanding on my part.
#import "ViewController.h"
#import "TracksMotion.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UIButton *startRecording;
#property (weak, nonatomic) IBOutlet UIButton *stopRecording;
#property (strong, nonatomic) TracksMotion *motionTracker;
#end
#implementation ViewController
#synthesize motionTracker = _motionTracker;
- (void)startMyMotionDetect
{
[self.motionTracker startsTrackingMotion];
}
#end
The motionTracker has a public API for the method startsTrackingMotion so I don't know why this doesn't work.
#import <Foundation/Foundation.h>
#import <CoreMotion/CoreMotion.h>
#interface TracksMotion : NSObject
- (void)startsTrackingMotion;
- (void)stopTrackingMotion;
#property (strong, nonatomic) CMMotionManager *motionManager;
#end
Properties / instance variables are not magically initialized for you. When you say:
#property (strong, nonatomic) TracksMotion *motionTracker;
... you are just reserving memory space for an instance variable (and generating a getter and a setter method through #synthesize or autosynthesis). There is no actual TracksMotion object there until you put one there. You must write code to do that. You must create or obtain a TracksMotion instance and assign it to self.motionTracker at some point, presumably early in the life of self (in this case, that's a ViewController instance). Until you run code that does that, self.motionTracker is nil.
(It is possible that you are being confused because it looks like outlets are automatically initialized. For example, you've got #property (weak, nonatomic) IBOutlet UIButton *startRecording; And sure enough, self.startRecording is a button. But that's because the nib-loading process does for you the very thing I'm saying you must do: it makes a button from the storyboard or .xib file, and assigns it to this instance variable.)
I have a subclassed UIView called TargetView that is contained in a UIViewController called MainViewController. I want to set MainViewController as the delegate for TargetView so that MainViewController can receive messages from the child view (TargetView).
In my MainViewController (UIViewController) header I have the following:
#import <UIKit/UIKit.h>
#import "TargetView.h"
#class TargetView;
#interface MainViewController : UIViewController <TargetViewDelegate>
#property (strong, nonatomic) IBOutlet TargetView *target;
#property (strong, nonatomic) IBOutlet UILabel *lblResults;
#end
When I set the TargetViewDelegate in the interface declaration, it shows up in code completion so it knows that it's there, but then the build fails with the message: can't find protocol declaration..."
In my TargetView (UIView) class I have the following:
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "MainViewController.h"
#protocol TargetViewDelegate
#required
-(void)receivedTargetTap;
#end
#interface TargetView : UIView{
id<TargetViewDelegate> delegate;
}
#property (nonatomic,strong) NSString *lblResults;
#property (nonatomic,weak) id<TargetViewDelegate> delegate;
#end
Creating custom delegates is uncharted territory for me. Can anyone tell me what I'm doing wrong? Thanks!
I believe your TargetView.h should be :
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#protocol TargetViewDelegate <NSObject>
#required
-(void)receivedTargetTap;
#end
#interface TargetView : UIView
#property (nonatomic, strong) NSString *lblResults;
#property (nonatomic, weak) id<TargetViewDelegate> delegate;
#end
MainViewController.h :
#import <UIKit/UIKit.h>
#import "TargetView.h"
#interface MainViewController : UIViewController <TargetViewDelegate>
#property (strong, nonatomic) IBOutlet TargetView *target;
#property (strong, nonatomic) IBOutlet UILabel *lblResults;
#end
From your code, you must add <NSObject> after your protocol definition, and remove the MainViewController.h import in your TargetView class.
I think there might be a problem with your import statements in both .h files.
Why do you reference MainViewController.h from TargetView.h? It seems like you don't need it. On the other hand, you should remove the forward declaration of #class TargetView in MainViewController.h, and the simple #import "TargetView.h" should be enough.
After that, you'll also need to implement the required - (void)receivedTargetTap;, otherwise the compiler will complain again that the TargetViewDelegate is not fully implemented.
For example one, I declare an object inside the interface brace {} like:
#interface testViewController : UIViewController {
IBOutlet UILabel * myLabel;
}
#property (retain, nonatomic) UILabel *myLabel;
#end
and example two, I declare an object outside the inferface brace {} like:
#interface testViewController : UIViewController {
}
#property (retain, nonatomic) IBOutlet UILabel *myLabel;
#end
I run the code and the result is the same, so I want to ask what is the different for decalare an object inside or outside the interface brace {}?
Thanks
The modern Objective-C runtimes (64-bit Mac OS X and iOS) will generate the backing store for your declared properties when you #synthesize them. So you don't need to declare them within the braces.
If you are declaring an iVar that is not a property and will only be used by the class, then they need to be declared. It's a good idea to mark these #private e.g
#interface MyClass : NSObject {
#private
NSString *privateString;
}
#property (nonatomic, copy) NSString *publicString; // be sure to #synthesize this
#end
In the second example you only declare a property. Xcode will declare object automatically.