为UIView创建子类以获得可重用性

时间:2015-05-26 03:30:35

标签: ios objective-c uiview subclass uitapgesturerecognizer

我有一个DiscoverViewController.h和.m文件,它们有一个函数可以替换要发现的场所的视图。我想在输出视图控制器中重用此视图。带有的DicoverViewController.m的代码如下:

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;
}                 

名为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];
}

不知怎的,这是行不通的。框架不会显示在正确的空间中,并且水龙头根本不起作用。我是否需要将其更改为类引用与实例?如何重用此类(DiscoverView)并使其正常工作?

感谢。

2 个答案:

答案 0 :(得分:1)

你的想法非常好,我认为你是在正确的方式......你刚刚犯了一些错误:

- (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功能,以便我们直接从Storyboard中显示结果(但这不是您在此主题中要求的内容。)

<强>更新

正如@abhishekkharwar所说,还有很多其他方法可以做到这一点,例如使用UICollectionViewUITableView,但您必须决定什么更适合您的应用需求。试着不要重新发明轮子。

答案 1 :(得分:1)

将名为DiscoverView.h的UIView类更改为

- (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;