I have a class called cell.h
#import <UIKit/UIKit.h>
#interface TokenCell : UITableViewCell
#property (strong, nonatomic) IBOutlet UILabel *idlabel;
#property (strong, nonatomic) IBOutlet UILabel *tokenlabel;
#end
In this app im trying to retrieve data from a server using Restkit, but this works right, the issue is more simple. I cant make a reference of this objects on Main.storyboard, XCode 5 just doesn't let me do this and the label properties that I created dont show in any way. I cant find where is the issue, so some help will be welcome. This Is very strange, because on my last test app I didn't have any problems doing this.
Just check you have given the class name in the storyboard file.
Check that you've specified TokenCell as the custom class for your UITableView cells:
(Here are 2 images to illustrate - I can't show inline images as I am new to StackOverflow!)
1. image - highlight the cell in your Main.storyboard
2. image - set the class to TokenCell, then save
Related
There are at least 3 methods of creating an IBOutlet in Objective-C, for making iOS 10 App, in Xcode 8.
Method 1: in ViewController.h
#interface ViewController : UIViewController
#property (nonatomic, strong) UILabel *textLabel;
#end
Method 2: in the interface of ViewController.m
#interface ViewController () {
IBOutlet UILabel *textLabel;
}
#end
Method 3: in the interface of ViewController.m, using #property
#interface ViewController ()
#property (nonatomic, strong) UILabel *textLabel;
#end
Given that the textLabel has to be accessed & its text is needed to be updated frequently, which method is the correct way to do so?
That all depends on whether you need your outlet to be accessible to classes outside of the containing one; generally I would discourage this because it is good practice to keep your view controllers responsible for updating your UI and not pass this task around to other classes. With this being said, Method 3 would be the best option, however, if you do have to access your object from another class, then simply use Method 1 so it is exposed in your class header.
Method 2 utilises iVars rather than object properties and is not the proper way to declare outlets, it may even cause unexpected behaviour so it is best to avoid this method.
Your code contains no proper IBOutlet. Outlets are connections to Storyboard.
Method 1
This is a property. As it is in .h file, it can be reached from outside. The Objective-C pattern for public.
Method 2
This is an iVar. Do not use iVars if you do not have to.
Method 3
This is a property. As it is in .m file, it can not be reached from outside. The Objective-C pattern for private.
Method 4
A proper IBOutlet looks like this:
#interface ViewController ()
#property (nonatomic, weak) IBOutlet UILabel *label;
#end
It is a simple property. You have to decide if you put it in .h or .m file depending on whether or not you want to publish it.
The IBOutlet simply makes the property connect-able to Storyboard. It's an annotation for Xcode and does not alter the semantic of your code.
Edit 1:
As Sulthan correctly mentions in the comments:
In most situations the correct design pattern is to hide outlets because it's an implementation detail. External classes should not set data directly using views.
Edit 2:
Why "not to use iVars if you do not have to" (2)
Opinion based:
I consider it as good OOP practice to use getters & setters (and thus not to access the variables directly). Also code is easier to read as you know while reading what x = self.variable (property) and x = variable (local variable) are.
If you have to use iVars for some reason, it is common to (and I would recommend to) prefix the name with _. x = _variable (iVar).
I am using cbpowell/MarqueeLabel class in my project. I changed the class of a Label from UILabel to MarqeeLabel. This got my Label to scroll. But it is in its Default MLLeftRight. I need to change it to MLContinous. How can I make this happen? I tried add a User Defined RunTime attribute, but that doesn't work. I cannot add "marqueeType" in the program, because my label is still in the UILabel class instead of MarqueeLabel, so can only access the methods for UILabel.
Anyone with experience in MarqueeLabel, please advice.
Or if you can tell me, how I can access the methods of a custom class I set(here- MarqueeLabel) for my label (instead of- UILabel)
You can create an IBOutlet for MarqueeLabel like
#property (weak, nonatomic) IBOutlet MarqueeLabel *mLabel;
Since it deoesn't support IBInspectable for marqueeType, you can configure label like
self.mLabel.marqueeType = MLLeftRight;
as i see the answer Visit IBOutlet and IBAction
the highest voted answer said “If you're not going to be using Interface Builder at all, then you don't need them in your code”
i fill confused when i see somebody's code like this
#import <UIKit/UIKit.h>
#interface ParallaxHeaderView : UIView
#property (nonatomic) IBOutlet UILabel *headerTitleLabel;
#property (nonatomic) IBOutlet UIImageView *headerImageView;
#end
are there any tips beyond my shallow knowledge?
Sometimes when the code might be used in other projects, the developer will provide the ability for the end user to choose the default programmatic interface, or design her own interface in IB.
Since distinct initialization methods (initWithFrame:, initWithCoder: etc..) will be triggered based on whether the code is called programmatically or through IB, one can provide such options.
But I agree that it's a rather special use case.
I'm trying to follow this tutorial: http://docs.opencv.org/doc/tutorials/ios/video_processing/video_processing.html
I have followed the steps but in the viewController.h file, it tells you to type "using namespace cv;" near the top of the file.
Xcode sees this as an error. And it won't let me build. How do I fix this?
Using XCode 4.6.3 and I can't tell what version of openCV I'm using but I just downloaded, so it's probably the latest. Also, I know that I've imported the opencv framework.
Here are the lines of code in viewController.h:
#import <UIKit/UIKit.h>
#import <opencv2/highgui/cap_ios.h>
using namespace cv;
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIButton *button;
#property (weak, nonatomic) IBOutlet UIImageView *imageView;
- (IBAction)actionStart:(id)sender;
#end
Try changing the extension of your ViewController from .m to .mm. That signals to the compiler that you would like to write that piece of code in Objective C++.
Edit: For additional information on how to write code effectively this way, check out this blog post.
My problem is a follows
I have a UIViewController subclass which holds a UISegmentedController and four tableviews that I layed out in interface builder.
#interface MultiTableHoldingView : UIViewController{
}
#property (strong, nonatomic) IBOutlet DataTV *dsDataTV;
#property (strong, nonatomic) IBOutlet EnviroTV *dsEnvironmentTV;
#property (strong, nonatomic) IBOutlet LocationTV *dsLocationTV;
#property (strong, nonatomic) IBOutlet Note_AnimalTV *dsNoteAnimal;
#property (strong, nonatomic) IBOutlet UISegmentedControl *diveElementSegmentController;
#property (strong, nonatomic) DiveSite* currentSite;
- (IBAction)diveElementSegmentControllerDidChange:(UISegmentedControl *)sender;
-(void) setFreshWaterColor;
-(void) setSaltwaterColor;
#end
setFreshWaterColor and setSaltWaterColour just set the background colour properties of the MultiTableHoldingView instances UIView and the four tableviews it contains. Both these method work fine when called from MultiTableHoldingView's viewDidLoad method. Heres one of them
-(void) setSaltwaterColor{
DLog(#"in set salt water colour");
self.view.backgroundColor= SaltWaterColor;
_dsLocationTV.backgroundColor=SaltWaterColor;
_dsDataTV.backgroundColor=SaltWaterColor;
_dsEnvironmentTV.backgroundColor=SaltWaterColor;
_dsNoteAnimal.backgroundColor=SaltWaterColor;
}
The other is the same except sets to FreshWaterColor - both are #define i have set up.
I use the segmentedController to turn the hidden properties of the various tableviews on and off. All nice and simple. The tableviews are pulling in their data. Working fine.
When selecting one of my tableview cells on one of the tableViews I want to change the background colour of both my tableview ( in fact all of my tableviews ) and the UIView that is the superview
self.superview.backgroundColor = FreshWaterColor;
works fine for reaching back and changing the instance of MultiTableHoldingView views background property but I want to call the instance of MultiTableHoldingView's setFreshWaterColor and setSaltwaterColor methods.
I have imported MultiTableHoldingViews header into the relevant tableview (EnviroTV), so it knows about it its superviews methods. But if I try to call either of the two methods on self.superview the methods do not show up and if i type them in full I get an the following error
no visible interface for 'UIView' shows the selector 'setFreshWaterColor'
So i checked what kind of object the superview was and its a "class of superview UIViewControllerWrapperView"
I search on this and its apparently "
This is a private view used by the framework. You're not supposed to modify it or whatsoever."
I'm obviously missing something here - how should i call the method on the instance of MultiTableHoldingView ?
Thanks in advance
Simon
Doh - its just delegation as danypata mentions in the comments - i've posted exactly how I did this as an answer below. Tried to make it as clear as possible how delegation works
THE SOLUTION
Step one - get more sleep before coding .
This really is basic objective-c stuff - I just went off at a tangent, looking for someway else to do it, getting confused by my discovery of UIViewControllerWrapperView along the way.
The solution, as danypata rightly suggests in the comments, is to use delegate -a common design pattern in Objective-C - just like you do, for example, when you use another class to supply tableview data
As I've been a numpty and wasted hours of my time today I'll try and make the 'how' clear for other relative newbies or people having an off day and not thinking straight.
In my case I set this up as follows
In my subview class's interface file - EnviroTV.h - I define the following protocol just before the #interface declaration
#protocol EnviroTVProtocol <NSObject>
-(void) setFreshWaterColor;
-(void) setSaltwaterColor;
#end
Then in the #interface section of the same file I add a property of type id which must conform the protocol I just declared .
#property (nonatomic, strong ) id<EnviroTVProtocol> colorChangeDelegate;
You make the type an id - a generic object - as you really don't care what kind of object is going to act as your delegate just that it implement the methods that you need it to run. When an object declares itself to implement a protocol its just promising to implement the method(s) that are required by the protocol
So, when I want to run the methods on the superviews class I call
[self.colorChangeDelegate setFreshWaterColor];
Or
[self.colorChangeDelegate setSaltWaterColor];
The final piece of the delegation pattern is to go into the class thats going to be the delegate (in this case my MultiTableHoldingView class ) and state that it conforms to the protocol
I do this in the MultiTableHoldingView.h file
Changing this line :
#interface MultiTableHoldingView : UIViewController
into this line :
#interface MultiTableHoldingView : UIViewController <EnviroTVProtocol>
means this class promises to implement all the required methods of the EnviroTVProtocol.
Luckily I had already written the two methods. So when I compiled it ran correctly
Newbies - don't be afraid of delegation - its awesome and not as complex as you first imagine it to be
Meanwhile, if anyone can explain what UIViewControllerWrapperView is .....