问题
I'm currently refactoring a couple of view controllers that share a few IBOutlet
s and IBAction
methods. I moved the outlet declarations and the IBAction
method into a superclass, cutting these out of the subclasses.
Now, when I open up Interface Builder, I find that I can't see the outlets or actions declared in the superclass. The connections still exist, as I'd wired them up before the refactoring, but they're grayed out. (It's important to note that the connections also WORK, as my action fires on a button press, and my outlets are modified properly.)
The question is, how can I get interface builder to recognize outlets from a superclass? Is this possible, and, if not, what do you all recommend?
(Just for fun, here's my superclass header file:)
@interface TFMainViewController : UIViewController {
UIImageView *logoImage, *thinkfunImage;
UIButton *buyFullButton;
}
@property (nonatomic, retain) IBOutlet UIImageView *logoImage, *thinkfunImage;
@property (nonatomic, retain) IBOutlet UIButton *buyFullButton;
-(IBAction) buyFullVersion;
@end
EDIT: in case anyone's wondering, I'm using Xcode and IB 3.2.5, with the iOS 4.2 SDK.
回答1:
I didn't realize it was even possible to connect to superclasses in interface builder until about an hour ago. Since this was the only question I could find regarding how to do this, I'll add my answer, even though this question is old. My answer is with regard to Xcode 4, not Xcode 3.
As far as I can tell, you can't connect to outlets in a superclass using the assistant editor, but you can do it by clicking on "File's Owner" in IB. That should show all the outlets in Utilities->Connections Inspector. You can then Ctrl+Click on the outlet in the inspector (click on the '+' sign), and drag it over to your view in IB.
回答2:
The solution for the problem with the IBOutlet .. is to change the class type to the Base Class in the identity inspector
![](https://www.eimg.top/images/2020/03/23/cd669c886de8945136f6747c9b73c67d.png)
connect using Control + drag and drop and
![](https://www.eimg.top/images/2020/03/23/8be264da84606e961c59c56afcecb728.png)
change it back to the child class
![](https://www.eimg.top/images/2020/03/23/e86b5911547d6c6db6dcbb40ac139b40.png)
This works for me
BTW: i used Xcode 6
回答3:
IB should be able to see outlets from superclasses, I have done this a number of times with no issues. Are you sure you are importing the superclass correctly (using #import instead of @class)? IB needs some way to track back to the superclass.
回答4:
Switching between the super and subclass in the identity inspector allows you to connect your outlets across the classes. The only issue I found is when you attempt to do this with a UITableViewCell and its subclass. I wanted to re-assign the default textLabel and detailTextLabel instances to labels I create in Interface Builder. The workaround is to create substitute labels and then override the getters to point to these instead.
回答5:
I'm pretty sure that IB only looks at the actual class you're using to find outlets, and not at superclasses. I think that the easiest solution would be to leave the instance variable declarations in the superclass, but duplicate the @property
lines in each subclass.
回答6:
I'm doing this in XCode 3.2.6. I started with outlets connected to a class, and then made a subclass with additional outlets. When I changed the File's Owner class to the subclass, IB showed the superclass outlets as greyed out. I switched File's Owner to the superclass, then back to the subclass and now all outlets are showing not greyed out.
回答7:
The simplest way: create interface and implementation files for your subclass(es)!
Perfect example: Juggleware's awesome ShadowButton Subclass of UIButton.
Make sure to create the .h & .m files in your project.
NOTE: There is no need to #import
the header files at all since this is simply a class instance of UIButton.
In Interface Builder:
- Select the element you which to connect.
- Go to Utilities -> Identity Inspector
- Change the Class to your subclass (or superclass). NOTE: You might have to type in your subclass name and hit ENTER.
You're done!
Even if you have declared a basic class (UIButton) as IBOutlet in your header file like so...
// YourViewController.h
@interface YourViewController : UIViewController {
IBOutlet UIButton *mybutton;
}
...the class you've set in Interface Builder (ShadowButton) will overwrite it since it's in the view layer.
The best part about this approach is that your code doesn't have any messy dependency issues.
回答8:
On the project I am currently working, we have a BaseViewController
with a UIScrollView
as IBOutlet
and handles keyboard appearance/disappearance events and slides the content accordingly. At first, I could not connect to that IBOutlet
, than solved the problem like this, which is similar to Sosily's answer:
BaseViewController
has anIBOutlet
, calledcontentScrollView
. I can see 5 previously connected outlets, which areUIScrollViews
on otherUIViewControllers
, created by people who previously worked on the projectI tried to connect my
UIScrollView
as thecontentScrollView
. Although myUIViewController
is a subclass ofBaseViewController
, I cannot connect it.I tried to connect already connected
UIScrollViews
as thecontentScrollView
. Although allUIViewControllers
are subclasses ofBaseViewController
, I cannot connect them again, as well. So, I started to look for a trick.I have created the same
contentScrollView
IBOutlet
on my ownUIViewController
, connected thescrollView
to my owncontentScrollView
outlet and removed the one that I have just created.Now the scrollView is connected as
contentScrollView
to File's Owner, but the onlycontentScrollView
belongs to theBaseViewController
. Tested and verified that keyboard events are handled correctly.
回答9:
I ran into a similar problem with a superclass, but it was due to a bug in Xcode (8.2) where Interface Builder doesn't show outlets in the Connection Inspector if those outlets have been declared with a _Nullable
type annotation for Swift compatibility.
Using nullable
inside @property's parentheses appears to work around the problem.
This Xcode bug seems to affect outlets in any class (ie. not just superclasses).
回答10:
I had the same problem, and it turns out it was because in the superclass I had the IBOutlets declared as "_Nullable". Example:
@property (nonatomic, strong) IBOutlet UITableView *_Nullable mySuperTableView;
When I removed the _Nullable, suddenly the IBOutlets reappeared in IB and all was good again. (I had only set them to _Nullable because Xcode was complaining "pointer is missing a nullability type specifier"... (don't know why). )
来源:https://stackoverflow.com/questions/4431881/how-to-access-iboutlets-declared-in-superclass