为 UIView 创建子类以实现可重用性
Creating a subclass for a UIView for reusability
我有一个 DiscoverViewController.h 和 .m 文件,它们具有替换要发现的地方的视图的功能。我也想在输出视图控制器中重用这个视图。 DicoverViewController.m 和 uiview 的代码如下:
for (PFObject *views in objects)
{
// Get the discoverr view setup
CGRect frame = CGRectMake(5.0, _viewStart, 310.0, viewHeight);
DiscoverView *parent = [[DiscoverView alloc] init];
[parent buildDiscoverViewWithFrame:frame andObjects:replies];
// UIView *parent = [[UIView alloc] initWithFrame:CGRectMake(5.0, _viewStart, 310.0, viewHeight)];
parent.backgroundColor = [UIColor whiteColor];
// parent.layer.cornerRadius = 2.0;
parent.layer.borderColor = [UIColor regularColor].CGColor;
parent.layer.borderWidth = 1.0f;
parent.tag = 1000 + _step;
// Add the label counter
// Add discover id for testing (is unique id)
UILabel *placeholder = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 10.0, 310.0, 12.0)];
placeholder.backgroundColor = [UIColor clearColor];
placeholder.textAlignment = NSTextAlignmentCenter;
placeholder.textColor = [UIColor bestTextColor];
placeholder.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:(12.0)];
placeholder.Text = [NSString stringWithFormat:@"%@", views.objectId];
[parent addSubview:placeholder];
// Increase size of content view
CGRect newContentView = _contentView.frame;
newContentView.size.width = _contentView.frame.size.width;
newContentView.size.height = _contentView.frame.size.height + bestHeight;
[_contentView setFrame:newContentView];
[_contentView addSubview:parent];
scrollView.contentSize = _contentView.frame.size;
// Adjust the postions
_viewStart = _viewStart + viewHeight - 1.0;
_step = _step + 1;
}
uiviewclass叫DiscoverView.h
#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
@interface DiscoverView : UIView
- (UIView *) buildDiscoverViewWithFrame:(CGRect) frame andObjects:(PFObject *) objects;
@end
实现文件DiscoverView.m:
- (UIView *) buildDiscoverViewWithFrame:(CGRect) frame andObjects:(PFObject *) objects
{
UIView *discover = [[UIView alloc] initWithFrame:frame];
_photoObject = objects.objectId;
//Add a gesture to dismiss keyboard on tap
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(discoverTapPressed)];
[discover addGestureRecognizer:tap];
return discover;
}
- (void) discoverTapPressed
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"The id is:"
message:_photoObject
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
不知何故这无法正常工作。框架不会显示在右侧 space 并且点击根本不起作用。我是否需要将其更改为 class 引用而不是实例?如何重复使用此 class (DiscoverView) 并使其正常工作?
谢谢。
你的想法很好,我认为你的方法是对的......你只是犯了一些错误:
- (UIView *)buildDiscoverViewWithFrame:(CGRect) frame andObjects:(PFObject *) objects
{
//Your method name is buildDiscoverView, but you are making a view
//that is not a DiscoverView class.
UIView *discover = [[UIView alloc] initWithFrame:frame];
//Tap gesture stuff...
return discover;
}
并且:
DiscoverView *parent = [[DiscoverView alloc] init];
//parent will not contain an attached tap gesture, but the view
//returned from its method does...
[parent buildDiscoverViewWithFrame:frame andObjects:replies];
//Ex:
//UIView *viewWithYourTapGesture = [parent buildDiscoverViewWithFrame:frame andObjects:replies];
我很确定这不是您真正想要的。我认为您正在尝试构建一个 DiscoveryView 实例,对吗?你可以这样做:
在你的DiscoveryView.m
- (id)initWithFrame:(CGRect)frame andObjects:(PFObject *)objects {
//You can call initWithFrame: method here as our base constructor
self = [super initWithFrame:frame];
if (self) {
//Add tap gesture here
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(discoverTapPressed)];
[self addGestureRecognizer:tap];
//and maybe do some other stuff as changing the background color
//or making the border stuff that you are doing outside...
}
return self;
}
现在您可以按如下方式初始化您的实例:
在你的DiscoverViewController.m
DiscoverView *parent = [[DiscoverView alloc] initWithFrame:frame andObjects:replies];
//If you do this on init, you don't need this anymore...
//parent.backgroundColor = [UIColor whiteColor];
//parent.layer.cornerRadius = 2.0;
//parent.layer.borderColor = [UIColor regularColor].CGColor;
//parent.layer.borderWidth = 1.0f;
仅供参考:我还建议您检查新的 IBDesignable
功能,它允许我们直接从情节提要中可视化结果(但这不是您在此线程中要求的。)
更新:
正如@abhishekkharwar 所说,还有许多其他方法可以更好地做到这一点,例如使用 UICollectionView
或 UITableView
,但您必须决定哪种方法更适合您的应用程序需求。尽量不要重新发明轮子。
将名为 DiscoverView.h 的 UIView class 更改为
- (id)initWithFrame:(CGRect)frame andObjects:(PFObject *)objects;
将实现文件 DiscoverView.m 更改为:
@interface DiscoverView ()
@property (nonatomic, strong) id photoObject;
@end
@implementation DiscoverView
- (id)initWithFrame:(CGRect)frame andObjects:(PFObject *)objects {
//You can call initWithFrame: method here as our base constructor
self = [super initWithFrame:frame];
if (self) {
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(discoverTapPressed)];
[self addGestureRecognizer:tap];
_photoObject = objects.objectId;
self.backgroundColor = [UIColor whiteColor];
self.layer.cornerRadius = 2.0;
self.layer.borderColor = [UIColor redColor].CGColor;
self.layer.borderWidth = 1.0f;
}
return self;
}
- (void) discoverTapPressed
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"The id is:"
message:_photoObject
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
替换旧代码中的代码:
DiscoverView *parent = [[DiscoverView alloc] init];
[parent buildDiscoverViewWithFrame:frame andObjects:replies];
// UIView *parent = [[UIView alloc] initWithFrame:CGRectMake(5.0, _viewStart, 310.0, viewHeight)];
parent.backgroundColor = [UIColor whiteColor];
// parent.layer.cornerRadius = 2.0;
parent.layer.borderColor = [UIColor regularColor].CGColor;
parent.layer.borderWidth = 1.0f;
parent.tag = 1000 + _step;
到
DiscoverView *parent = [[DiscoverView alloc] initWithFrame:frame andObjects:replies];
parent.tag = 1000 + _step;
我有一个 DiscoverViewController.h 和 .m 文件,它们具有替换要发现的地方的视图的功能。我也想在输出视图控制器中重用这个视图。 DicoverViewController.m 和 uiview 的代码如下:
for (PFObject *views in objects)
{
// Get the discoverr view setup
CGRect frame = CGRectMake(5.0, _viewStart, 310.0, viewHeight);
DiscoverView *parent = [[DiscoverView alloc] init];
[parent buildDiscoverViewWithFrame:frame andObjects:replies];
// UIView *parent = [[UIView alloc] initWithFrame:CGRectMake(5.0, _viewStart, 310.0, viewHeight)];
parent.backgroundColor = [UIColor whiteColor];
// parent.layer.cornerRadius = 2.0;
parent.layer.borderColor = [UIColor regularColor].CGColor;
parent.layer.borderWidth = 1.0f;
parent.tag = 1000 + _step;
// Add the label counter
// Add discover id for testing (is unique id)
UILabel *placeholder = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 10.0, 310.0, 12.0)];
placeholder.backgroundColor = [UIColor clearColor];
placeholder.textAlignment = NSTextAlignmentCenter;
placeholder.textColor = [UIColor bestTextColor];
placeholder.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:(12.0)];
placeholder.Text = [NSString stringWithFormat:@"%@", views.objectId];
[parent addSubview:placeholder];
// Increase size of content view
CGRect newContentView = _contentView.frame;
newContentView.size.width = _contentView.frame.size.width;
newContentView.size.height = _contentView.frame.size.height + bestHeight;
[_contentView setFrame:newContentView];
[_contentView addSubview:parent];
scrollView.contentSize = _contentView.frame.size;
// Adjust the postions
_viewStart = _viewStart + viewHeight - 1.0;
_step = _step + 1;
}
uiviewclass叫DiscoverView.h
#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
@interface DiscoverView : UIView
- (UIView *) buildDiscoverViewWithFrame:(CGRect) frame andObjects:(PFObject *) objects;
@end
实现文件DiscoverView.m:
- (UIView *) buildDiscoverViewWithFrame:(CGRect) frame andObjects:(PFObject *) objects
{
UIView *discover = [[UIView alloc] initWithFrame:frame];
_photoObject = objects.objectId;
//Add a gesture to dismiss keyboard on tap
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(discoverTapPressed)];
[discover addGestureRecognizer:tap];
return discover;
}
- (void) discoverTapPressed
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"The id is:"
message:_photoObject
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
不知何故这无法正常工作。框架不会显示在右侧 space 并且点击根本不起作用。我是否需要将其更改为 class 引用而不是实例?如何重复使用此 class (DiscoverView) 并使其正常工作?
谢谢。
你的想法很好,我认为你的方法是对的......你只是犯了一些错误:
- (UIView *)buildDiscoverViewWithFrame:(CGRect) frame andObjects:(PFObject *) objects
{
//Your method name is buildDiscoverView, but you are making a view
//that is not a DiscoverView class.
UIView *discover = [[UIView alloc] initWithFrame:frame];
//Tap gesture stuff...
return discover;
}
并且:
DiscoverView *parent = [[DiscoverView alloc] init];
//parent will not contain an attached tap gesture, but the view
//returned from its method does...
[parent buildDiscoverViewWithFrame:frame andObjects:replies];
//Ex:
//UIView *viewWithYourTapGesture = [parent buildDiscoverViewWithFrame:frame andObjects:replies];
我很确定这不是您真正想要的。我认为您正在尝试构建一个 DiscoveryView 实例,对吗?你可以这样做:
在你的DiscoveryView.m
- (id)initWithFrame:(CGRect)frame andObjects:(PFObject *)objects {
//You can call initWithFrame: method here as our base constructor
self = [super initWithFrame:frame];
if (self) {
//Add tap gesture here
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(discoverTapPressed)];
[self addGestureRecognizer:tap];
//and maybe do some other stuff as changing the background color
//or making the border stuff that you are doing outside...
}
return self;
}
现在您可以按如下方式初始化您的实例:
在你的DiscoverViewController.m
DiscoverView *parent = [[DiscoverView alloc] initWithFrame:frame andObjects:replies];
//If you do this on init, you don't need this anymore...
//parent.backgroundColor = [UIColor whiteColor];
//parent.layer.cornerRadius = 2.0;
//parent.layer.borderColor = [UIColor regularColor].CGColor;
//parent.layer.borderWidth = 1.0f;
仅供参考:我还建议您检查新的 IBDesignable
功能,它允许我们直接从情节提要中可视化结果(但这不是您在此线程中要求的。)
更新:
正如@abhishekkharwar 所说,还有许多其他方法可以更好地做到这一点,例如使用 UICollectionView
或 UITableView
,但您必须决定哪种方法更适合您的应用程序需求。尽量不要重新发明轮子。
将名为 DiscoverView.h 的 UIView class 更改为
- (id)initWithFrame:(CGRect)frame andObjects:(PFObject *)objects;
将实现文件 DiscoverView.m 更改为:
@interface DiscoverView ()
@property (nonatomic, strong) id photoObject;
@end
@implementation DiscoverView
- (id)initWithFrame:(CGRect)frame andObjects:(PFObject *)objects {
//You can call initWithFrame: method here as our base constructor
self = [super initWithFrame:frame];
if (self) {
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(discoverTapPressed)];
[self addGestureRecognizer:tap];
_photoObject = objects.objectId;
self.backgroundColor = [UIColor whiteColor];
self.layer.cornerRadius = 2.0;
self.layer.borderColor = [UIColor redColor].CGColor;
self.layer.borderWidth = 1.0f;
}
return self;
}
- (void) discoverTapPressed
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"The id is:"
message:_photoObject
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
替换旧代码中的代码:
DiscoverView *parent = [[DiscoverView alloc] init];
[parent buildDiscoverViewWithFrame:frame andObjects:replies];
// UIView *parent = [[UIView alloc] initWithFrame:CGRectMake(5.0, _viewStart, 310.0, viewHeight)];
parent.backgroundColor = [UIColor whiteColor];
// parent.layer.cornerRadius = 2.0;
parent.layer.borderColor = [UIColor regularColor].CGColor;
parent.layer.borderWidth = 1.0f;
parent.tag = 1000 + _step;
到
DiscoverView *parent = [[DiscoverView alloc] initWithFrame:frame andObjects:replies];
parent.tag = 1000 + _step;