【问题标题】:How to achieve a "vertical reveal" effect on iOS, preferably with a UITableView如何在iOS上实现“垂直显示”效果,最好用一个UITableView
【发布时间】:2020-02-23 00:17:58
【问题描述】:

我正在尝试实现类似于this video 中可以看到的效果。

请注意,我说的是“垂直显示”效果,而不是“水平轮播”效果。

理想情况下,它应该与 UITableView 一起使用,但我知道这是不可能的。

【问题讨论】:

    标签: ios uitableview user-interface


    【解决方案1】:

    您可以通过创建具有 tableView 父级高度的页脚视图来实现此行为。

    class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
        var footer: UIView!
        var tableView: UITableView!
        let cellId = "CellID"
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let redView = UIView()
            redView.backgroundColor = UIColor.red
            redView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
            redView.center = self.view.center
            redView.autoresizingMask = [.flexibleLeftMargin, .flexibleTopMargin, .flexibleRightMargin, .flexibleBottomMargin]
            self.view.addSubview(redView)
    
            let footer = UIView()
            footer.backgroundColor = UIColor.clear
            let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))
            footer.addGestureRecognizer(tapRecognizer)
            self.footer = footer
    
            let tableView = UITableView()
            tableView.showsVerticalScrollIndicator = false
            tableView.backgroundColor = .clear
            tableView.dataSource = self
            tableView.delegate = self
            tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)
            tableView.frame = self.view.bounds
            tableView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
            self.view.addSubview(tableView)
            self.tableView = tableView
        }
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 5
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
            cell.textLabel?.text = "\(indexPath.row)"
            cell.backgroundColor = .green
            return cell
        }
    
        func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return 200
        }
    
        func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
            return self.footer
        }
    
        func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
            return self.view.bounds.height
        }
    
        @objc func handleTap(sender: UITapGestureRecognizer) {
            self.tableView.frame.origin.y = self.view.bounds.height
            self.tableView.contentOffset = .zero
            UIView.animate(withDuration: 1) {
                self.tableView.frame.origin.y = self.view.bounds.origin.y
            }
        }
    }
    
    

    【讨论】:

    • 谢谢你,马克,你的回答很有帮助。它确实适用于效果的第一部分,但不适用于第二部分(当广告下方的单元格从底部滚动时)
    • @ArielMalka 我在答案中添加了修改。主要思想是我们将内容偏移设置为零,通过将其移动到 viewController 视图的底部来隐藏表格视图,并以动画方式显示它,然后返回到 viewController 视图原点 y。该动画的触发器是 tableViewFooterView 上的点击手势。
    • 谢谢马克。我正在寻找一个解决方案,其中来自底部的单元格编号为 5、6、7 等,并定期拖动表格内容(即没有触发动画)。我实际上做了一些事情。完成后将分享...
    • 您可以将tableview放在背景视图之上。当应该显示后视图时,在该索引处添加一个具有清晰背景和高度等于 tableview 的 tableviewcell。还要保持表格视图的清晰背景。这样,tableview 将保持滚动,新的单元格将从底部出现。
    【解决方案2】:

    我最终做了以下事情:

    TableViewController.h

    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface TableViewController : UITableViewController
    
    @end
    
    NS_ASSUME_NONNULL_END
    

    TableViewController.m

    #import "TableViewController.h"
    #import "CustomCell.h"
    
    #define ROW 7
    #define ROW_HEIGHT 100
    
    @interface TableViewController ()
    
    @property (nonatomic, strong) CustomCell *customCell;
    
    @end
    
    @implementation TableViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"IDENTIFIER1"];
    
        self.customCell = [[CustomCell alloc] init];
    }
    
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
        return 1;
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return 20;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        if (indexPath.row == ROW) {
            return self.customCell;
        }
    
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"IDENTIFIER1" forIndexPath:indexPath];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.textLabel.text = [NSString stringWithFormat:@"%ld", indexPath.row];
        return cell;
    }
    
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        if (indexPath.row == ROW) {
            return self.tableView.frame.size.height;
        }
    
        return ROW_HEIGHT;
    }
    
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        CGFloat offsetY = scrollView.contentOffset.y;
        CGFloat top = ROW * ROW_HEIGHT;
    
        if (offsetY >= top - scrollView.frame.size.height) {
            self.customCell.mainView.frame = CGRectMake(0, offsetY - top, scrollView.frame.size.width, scrollView.frame.size.height);
        }
    }
    
    @end
    

    CustomCell.h

    #import <UIKit/UIKit.h>
    #import <WebKit/WebKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface CustomCell : UITableViewCell
    
    @property (nonatomic, strong) WKWebView *mainView;
    
    @end
    
    NS_ASSUME_NONNULL_END
    

    CustomCell.m

    #import "CustomCell.h"
    
    @implementation CustomCell
    
    - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
        if (self) {
            self.selectionStyle = UITableViewCellSelectionStyleNone;
            self.contentView.backgroundColor = UIColor.greenColor; // XXX
    
            WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
            self.mainView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
    
            NSURL *url = [NSURL fileURLWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"test1.htm"]];
            NSURLRequest *request = [NSURLRequest requestWithURL:url];
            [self.mainView loadRequest:request];
    
            self.mainView.scrollView.bounces = NO;
            self.mainView.scrollView.bouncesZoom = NO;
    
            [self.contentView addSubview:self.mainView];
            self.contentView.clipsToBounds = YES;
        }
    
        return self;
    }
    
    @end
    

    test1.htm

    <html>
        <head><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"></head>
        <style>
            body {
                margin: 24px;
                background-color: #ffff00;
                background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAAWdEVYdENyZWF0aW9uIFRpbWUAMTAvMjkvMTm1eHLxAAAAm0lEQVR4nO3QQRHAMAzAsGT8OWcw9KiFwOedmbu7nUd9OkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAK0BOkBrgA7QGqADtOcH7MycjpB+hI8Fez5BjwUAAAAASUVORK5CYII=");
                font-family: sans-serif;
                font-size: 160px;
                color: #ff0000;
            }
        </style>
    
        <script>
            function loop(timestamp) {
                var element = document.getElementById("main");
                element.innerText = timestamp;
    
                window.requestAnimationFrame(loop);
            }
    
            window.requestAnimationFrame(loop);
        </script>
    
        <body>
            <div id="main"></div>
        </body>
    </html>
    

    【讨论】:

      猜你喜欢
      • 2013-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多