自定义UIView (with xib)自动布局宽度和从委托推送视图控制器



我有问题设置约束自定义UIView和推新的ViewController委托当我点击视图。我试图找到解决这些问题的方法,但没有找到一个可以回答这些问题的方法。

自动布局问题

我有自定义xib文件已设置大小:自由形式,宽度:600和高度:25,它还包括一个标签和一个按钮在这个视图的约束。我已经在我想要的导航栏下面成功地添加了这个视图。问题是,它不做任何适合它的宽度与导航栏/窗口大小相等(我已经尝试了多种选择,如。为窗口/导航条宽度的视图创建新框架。它似乎只有600的静态宽度所有的时间,无论我尝试。

前两个约束是有效的,它出现在导航条下方25点并居中。但是最后一个是没用的。

我该如何正确地做这件事?到目前为止有这个:

[self.subView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:self.subView];
[self.view addConstraint:
 [NSLayoutConstraint constraintWithItem:self.subView
                              attribute:NSLayoutAttributeBottom
                              relatedBy:NSLayoutRelationEqual
                              toItem:self.navBar
                              attribute:NSLayoutAttributeBottom
                              multiplier:1
                              constant:25.0]];
[self.view addConstraint:
 [NSLayoutConstraint constraintWithItem:self.subView
                              attribute:NSLayoutAttributeCenterX
                              relatedBy:NSLayoutRelationEqual
                                 toItem:self.view
                              attribute:NSLayoutAttributeCenterX
                             multiplier:1.0
                               constant:0.0]];
[self.view addConstraint:
 [NSLayoutConstraint constraintWithItem:self.subView
                              attribute:NSLayoutAttributeWidth
                              relatedBy:NSLayoutRelationEqual
                                 toItem:self.view
                              attribute:NSLayoutAttributeWidth
                             multiplier:1
                               constant:0]];

我应该做更多的xib-file,它会使这个宽度适合它的父视图吗?我还实现了initWithFrame, initWithCoder和intrinsicContentSize到我的自定义视图。


<

解决方案/strong>

我最终使containerView为我的子视图和中心垂直和水平,并找到正确的宽度约束。我还忘记更新subView的视图帧来匹配导航条宽度。以下是我最终的结果(如果有更好的方法,我很乐意接受批评):

self.containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 62, self.navBar.frame.size.width, 25)];
[self.view addSubview:self.containerView];
self.subView = [[SubView alloc]init];
[self.subView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.containerView addSubview:self.subView];
self.subView.view.frame = CGRectMake(0, 0, self.containerView.frame.size.width, self.containerView.frame.size.height);
[self.containerView addConstraint:
 [NSLayoutConstraint constraintWithItem:self.subView
                              attribute:NSLayoutAttributeCenterY
                              relatedBy:NSLayoutRelationEqual
                                 toItem:self.containerView
                              attribute:NSLayoutAttributeCenterY
                             multiplier:1.0
                               constant:0.0]];
[self.containerView addConstraint:
 [NSLayoutConstraint constraintWithItem:self.subView
                              attribute:NSLayoutAttributeCenterX
                              relatedBy:NSLayoutRelationEqual
                                 toItem:self.containerView
                              attribute:NSLayoutAttributeCenterX
                             multiplier:1.0
                               constant:0.0]];
[self.containerView addConstraint:
 [NSLayoutConstraint constraintWithItem:self.subView
                              attribute:NSLayoutAttributeWidth
                              relatedBy:NSLayoutRelationEqual
                                 toItem:self.containerView
                              attribute:NSLayoutAttributeWidth
                             multiplier:1.0f
                               constant:0]];

委派问题(已解决)

这个问题的答案:请看下面格林老师的回答。

当我在自定义视图中使用委托创建UITapGestureRecognizer时发生了另一个问题。我想要的是当我点击视图时,它会打开另一个ViewController。委托函数是这样的在这里我实现了自定义视图:

-(void)pushViewControllerUsingDelegate
{
    NSLog(@"DELEGATE WAS : %@", self.subView.delegate);
    [self pushViewController:self.anotherViewController animated:YES];
}

现在当我点击视图时它给出了异常:

DELEGATE WAS : <MasterViewController: 0x7fc96132e7d0> <-- Delegate is OK
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<AnotherViewController 0x7fc961248230> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key subViewButton.'

这到底是什么意思?我有这个带有弱属性的subViewButton IBOutlet,它和这个有关系吗?还是有别的办法?

我遵循的教程:https://www.youtube.com/watch?v=TfKv1MYxnA4

因为没有足够的数据来确切地确定您遇到的问题是什么,所以我刚刚创建了一个正在工作的代码片段,并且正在做您想要得到的事情。

关于约束,我认为问题是缺失的高度约束(除非你在其他地方确定),试着记住,当你添加约束提供足够的数据编译器了解如何调整大小和定位你的子视图根据它的父视图,在你的情况下,它不知道什么是高度,因为你没有提供也没有底部或高度约束来确定它。

关于委托方法,你没有提供足够的数据来确切地确定问题是什么,所以我写了一些我认为正在做你想要得到的东西。

下面的代码片段经过测试并正常工作:

子视图:View.h

@protocol viewManager <NSObject>
@optional
- (void)subviewWasTapped;
@end
@interface View : UIView
@property (nonatomic, strong) id<viewManager>delegate;
@end

View.m

@implementation View
- (void)awakeFromNib{
    [super awakeFromNib];
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(viewWasTapped:)];
    [self addGestureRecognizer:tap];
}
- (void)viewWasTapped:(NSNotification *)notification
{
    [self sendViewWasTappedToDelegate];
}
- (void)sendViewWasTappedToDelegate
{
    @synchronized(_delegate)
    {
        if([_delegate respondsToSelector:@selector(subviewWasTapped)])
        {
            [_delegate subviewWasTapped];
        }
    }
}
@end

FirstViewController:

@interface ViewController () <viewManager>
@property (nonatomic, strong) View *subview;
@end
@implementation ViewController
@synthesize subview;
- (void)viewDidLoad {
    [super viewDidLoad];
    NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:@"View" owner:self options:nil];
    subview = [subviewArray objectAtIndex:0];
    [subview setTranslatesAutoresizingMaskIntoConstraints:NO];
    [self.view addSubview:subview];
    [self.view addConstraint:
     [NSLayoutConstraint constraintWithItem:subview
                                  attribute:NSLayoutAttributeTop
                                  relatedBy:NSLayoutRelationEqual
                                     toItem:self.topLayoutGuide
                                  attribute:NSLayoutAttributeBottom
                                 multiplier:1.0
                                   constant:0.0]];

     [self.view addConstraint:
      [NSLayoutConstraint constraintWithItem:subview
                                  attribute:NSLayoutAttributeCenterX
                                  relatedBy:NSLayoutRelationEqual
                                     toItem:self.view
                                  attribute:NSLayoutAttributeCenterX
                                 multiplier:1.0
                                   constant:0.0]];
     [self.view addConstraint:
      [NSLayoutConstraint constraintWithItem:subview
                                  attribute:NSLayoutAttributeWidth
                                  relatedBy:NSLayoutRelationEqual
                                     toItem:self.view
                                  attribute:NSLayoutAttributeWidth
                                 multiplier:1
                                   constant:0.0]];
    // Height constraint to determine the
    [self.view addConstraint:
     [NSLayoutConstraint constraintWithItem:subview
                                  attribute:NSLayoutAttributeHeight
                                  relatedBy:NSLayoutRelationEqual
                                     toItem:nil
                                  attribute:NSLayoutAttributeNotAnAttribute
                                 multiplier:1
                                   constant:25.0]];
    [self.view layoutIfNeeded];
    [subview setDelegate:self];
}
#pragma mark - viewManager delegate method 
- (void)subviewWasTapped{
    SecondeViewController *secondeVC = [self.storyboard instantiateViewControllerWithIdentifier:@"SecondeViewController"];
    [self.navigationController pushViewController:secondeVC animated:YES];
}

最新更新