制作触摸时上下滑动的UIView列表

时间:2014-07-07 16:31:07

标签: ios objective-c ios7

我试图想出一种方法来构建类似下图的图像,这是一个项目列表,当单击一个部分时,它会滑出内容。它在大多数网站上都是一个非常常见的用户体验,而不是。我的想法是让每个灰色框(按钮)滑出包含其他项目的UIView。我还是iOS开发的新手,但我很难找到如何让UIView动画下滑并将其下面的内容推下来。希望有人可以给我一个很好的起点或指向苹果文档范围之外的一些信息。

谢谢!

UIView list layout example

1 个答案:

答案 0 :(得分:1)

因此,如果您只有几个视图,我不会推荐UITableView方法,因为使用动画自定义并且表格视图通常希望用单元格填充整个屏幕。而是编写一个具有所需两种状态的可扩展UIView子类。添加一个方法以在扩展和折叠状态之间切换。在扩展/折叠时调整它们的位置,以便它们始终具有足够的空间。

我为您提供了调整帧数的示例。我想用自动布局约束做同样的事情应该很容易:给视图一个固定的高度约束,并在折叠/扩展时改变它。以相同的方式将视图之间的约束设置为0,以便它们堆叠在彼此之上。

可扩展视图:

@interface ExpandingView(){
    UIView *_expandedView;
    UIView *_seperatorView;

    BOOL _expanded;
}
@end

@implementation ExpandingView

- (id)init
{
    self = [super initWithFrame:CGRectMake(15, 0, 290, 50)];
    if (self) {
        _expanded = NO;
        self.clipsToBounds = YES;

        _headerView = [[UIView alloc] initWithFrame:self.bounds];
        _headerView.backgroundColor = [UIColor colorWithWhite:0.8 alpha:1];
        [self addSubview:_headerView];

        _seperatorView = [[UIView alloc] initWithFrame:CGRectMake(0, self.bounds.size.height-1, self.bounds.size.width, 1)];
        _seperatorView.backgroundColor = [UIColor lightGrayColor];
        [self addSubview:_seperatorView];

        _expandedView = [[UIView alloc] initWithFrame:CGRectOffset(self.bounds, 0, self.bounds.size.height)];
        _expandedView.backgroundColor = [UIColor blueColor];
        [self addSubview:_expandedView];
    }
    return self;
}

- (void)layoutSubviews{
    [self adjustLayout];
}

- (void)adjustLayout{
    _headerView.frame = CGRectMake(0, 0, self.bounds.size.width, 50);
    _seperatorView.frame = CGRectMake(0, 49, self.bounds.size.width, 1);
    _expandedView.frame = CGRectMake(0, 50, self.bounds.size.width, self.bounds.size.height-50);
}

- (void)toggleExpandedState{
    _expanded = !_expanded;
    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, _expanded?200:50);
    [self adjustLayout];
}

@end

的ViewController:

@interface ExpandingViewController (){
    NSArray *_expandingViews;
}
@end

@implementation ExpandingViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    _expandingViews = @[
                    [[ExpandingView alloc] init],
                    [[ExpandingView alloc] init],
                    [[ExpandingView alloc] init],
                    ];

    for(ExpandingView *view in _expandingViews){
        [view.headerView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(expandingViewTapped:)]];
        [self.view addSubview:view];
    }
}

- (void)viewWillLayoutSubviews{
    int y = 100;
    for(ExpandingView *view in _expandingViews){
        view.frame = CGRectOffset(view.bounds, (CGRectGetWidth(self.view.bounds)-CGRectGetWidth(view.bounds))/2, y);
        y+=view.frame.size.height;
    }
}

- (void)expandingViewTapped:(UITapGestureRecognizer*)tapper{
    ExpandingView *view = (ExpandingView*)tapper.view.superview;

    [UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.8 initialSpringVelocity:0 options:0 animations:^{
        [view toggleExpandedState];
        [self.view layoutIfNeeded];
    } completion:nil];    
}