如何在iOS 7中使用VFL

时间:2016-08-17 08:24:08

标签: ios objective-c ios7 autolayout

我创建了一个类:ZpTabBar; 该类需要添加子视图,这个子视图' name是ZpTabBarItem。

在ZpTabBarItem中,我想使用VFL并设计这个类。

你可以看到这个核心代码:

--------------------------------------
ZpTabBar add some ZpTabBarItem
--------------------------------------
- (void) setTabBarItems:(NSArray<ZpTabBarItem *> *)tabBarItems
{
    [self removeAllBackupSubviews] ;

    if( nil == tabBarItems || 0 == [tabBarItems count] ){
        return ;
    }

    NSUInteger tag = 0 ;
    for( ZpTabBarItem *item in tabBarItems ){
        [item setTag:tag] ;
        [self addSubview:item] ;
        [item initVFLAutoLayout] ; // Core code , init VFL
        if( self.delegate && [self.delegate respondsToSelector:@selector(zpTabBar:needUseVFLWithIndex:)] ){
            NSArray<id<ZpTabBarExcVFLModel>>* modelArr = [self.delegate zpTabBar:self needUseVFLWithIndex:tag] ;
            if( nil != modelArr && [modelArr count] > 0 ){
                [item removeZpTabBarItemAllConstraints] ;
                for( id<ZpTabBarExcVFLModel> model in modelArr ){
                    [item excLayoutWithExcVFLModel:model] ;
                }
            }
        }
        tag ++ ;
    }
    tag = 0 ;

    [self.backup_tabBarItems addObjectsFromArray:tabBarItems] ; // 把数据备份了
    [self adjustSubviewsFrame];
}

你可以看到ZpTabBatItem的initVFLAutoLayout

--------------------------------------
ZpTabBarItem
--------------------------------------
- (void) initVFLAutoLayout
{
    if( NO == self.pri_componentCompleteAutoLayout && self.iconV && self.titleL ){
        [self setPri_componentCompleteAutoLayout:YES] ;
        [self setTabBarItemModel:^ZpTabBarItemModel *{
            return self.tabBarItemModel ? self.tabBarItemModel : [[ZpTabBarItemModel alloc] init] ;
        }()] ; // 导入一个默认数据
        [self excLayoutWithVisulFormatString:@"V:|-topMargin-[iconV(==22)]-padding-[titleL]-bottomMargin-|" iconVFLKey:@"iconV" titleVFLKey:@"titleL" options:NSLayoutFormatAlignAllCenterX metrics:@{@"topMargin":@6,@"bottomMargin":@2,@"padding":@2}] ; // 界面
        [self excLayoutWithVisulFormatString:@"H:[iconV(==22)]" iconVFLKey:@"iconV" titleVFLKey:nil options:NSLayoutFormatAlignAllCenterY metrics:nil] ;
        [self excLayoutWithVisulFormatString:@"H:|-[titleL]-|" iconVFLKey:nil titleVFLKey:@"titleL" options:NSLayoutFormatAlignAllLeading|NSLayoutFormatAlignAllTrailing metrics:nil] ;
    }
}


- (void) layoutSubviews
{
    [super layoutSubviews] ;
    [self.onClickButton setFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)] ;
    [self bringSubviewToFront:self.onClickButton] ;
}

执行应用程序并启动App ....... 错误! Xcode IDE为你的应用程序引发了错误:

-----------------------------
**Error description:**
-----------------------------
2016-08-17 16:00:09.526 YaoCaiBao[834:60b] *** Assertion failure in -[ZpTabBarItem layoutSublayersOfLayer:], /SourceCache/UIKit/UIKit-2935.137/UIView.m:8794
2016-08-17 16:00:09.528 YaoCaiBao[834:60b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. ZpTabBarItem's implementation of -layoutSubviews needs to call super.'
*** First throw call stack:
(0x2f329fd3 0x39ba2ccf 0x2f329ead 0x2fcd6d5b 0x31b45e39 0x317c362b 0x317bee3b 0x317beccd 0x317be6df 0x317be4ef 0x31bc4a0b 0x31baf927 0x31b4b709 0x31b4a871 0x31baecc9 0x341b7aed 0x341b76d7 0x2f2f4ab7 0x2f2f4a53 0x2f2f3227 0x2f25df0f 0x2f25dcf3 0x31badef1 0x31ba916d 0x186a61 0x3a0afab7)
libc++abi.dylib: terminating with uncaught exception of type NSException

问题: 1,为什么VFL有错误?

2,如何解决这个问题?

请帮助,谢谢...

1 个答案:

答案 0 :(得分:0)

错误代码:

- (void) layoutSubviews
{
    [super layoutSubviews] ;
    [self.onClickButton setFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)] ;
    [self bringSubviewToFront:self.onClickButton] ;
}

成功代码:

- (void) layoutSubviews
{
    [self.onClickButton setFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)] ;
    [self bringSubviewToFront:self.onClickButton] ;
    [super layoutSubviews] ;
}