V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhlooking
V2EX  ›  iOS

知乎 iOS App 里,发现->推荐,推荐里面上半部分轮播的图片是如何随着 TableView 的滚动而滚动的?

  •  
  •   zhlooking · 2016-05-19 15:20:06 +08:00 · 4423 次点击
    这是一个创建于 2899 天前的主题,其中的信息可能已经有所发展或是发生改变。
    26 条回复    2016-05-20 15:02:00 +08:00
    codeisjobs
        1
    codeisjobs  
       2016-05-19 15:35:14 +08:00 via iPhone
    手势吧,监听向上滑动的手势,再让它跟着一起动,没写过,不确定是不是这样实现的
    gnouveau
        2
    gnouveau  
       2016-05-19 15:45:15 +08:00
    在 tableView 的 `scrollViewDidScroll:`里调整那个 view 的 original
    zhlooking
        3
    zhlooking  
    OP
       2016-05-19 16:39:50 +08:00
    @codeisjobs 如果要精细的确定滑动位移的多少就要用到 2 楼 @gnouveau 所说的'scrollViewDidScroll:'方法。可是这个时候 tableView 的 offsetY 已经改变了,就不是知乎的效果了。
    chmlai
        4
    chmlai  
       2016-05-19 16:43:47 +08:00
    直接 KVO contentOffset
    zhlooking
        5
    zhlooking  
    OP
       2016-05-19 16:54:03 +08:00
    @chmlai tableView 向上滑的的时候 contentOffset 看起来是没有变化的。
    zhlooking
        6
    zhlooking  
    OP
       2016-05-19 17:05:06 +08:00
    @chmlai @codeisjobs @gnouveau 有没有可能是在 UIScrollView 中嵌套了上面的 UIScrollVeiw 和下面的 UITableView ?
    l12ab
        7
    l12ab  
       2016-05-19 17:49:14 +08:00
    没下载在知乎,但根据你描述觉得是 tableview 的 header
    misaka15
        8
    misaka15  
       2016-05-19 17:52:36 +08:00
    直接放在 tableView 中的 headerView
    zhlooking
        9
    zhlooking  
    OP
       2016-05-19 17:52:54 +08:00
    @l12ab 确定不是 headerView ,已经有下拉刷新的控件占据 headerView 的位置了。
    misaka15
        10
    misaka15  
       2016-05-19 17:58:53 +08:00
    @zhlooking 如果是这样的,那你只能楼上那个哥们说的那样,要么 KVO 监听 CotentOffset ,要么在 scrollViewDidScroll 里实现
    a412739861
        11
    a412739861  
       2016-05-19 18:03:08 +08:00
    @zhlooking
    在轮播的图片部分,上下滑动是无法滚动界面的,所以事件不会传到下面的 uitableview 。应该是平级的吧,倾向你说的那种,不过也没什么特别的意义吧?
    LINAICAI
        12
    LINAICAI  
       2016-05-19 18:07:18 +08:00
    。。。明显是 UIScrollView 下装了四个控制器的 view ,然后第一个 view 就是推荐的,上面放广告轮播图,下面放 tableView
    zhlooking
        13
    zhlooking  
    OP
       2016-05-19 18:19:30 +08:00
    @misaka15 监听 ContentOffset 我尝试了,可是这个 TableView 的 contentOffset 并没有改变。
    @a412739861 如果像我所说的是 UIScrollView 中嵌套了 UIScrollView 和 UITableView ,那么这些嵌套的手势又是如何区分开的?也就是我滑动 UITableView 的时候如何让 UIScrollView 来处理这个事件?
    wddwycc
        14
    wddwycc  
       2016-05-19 18:42:58 +08:00 via iPhone
    contentInset 啊, Inset 出来的空间放轮播控件
    zhlooking
        15
    zhlooking  
    OP
       2016-05-19 19:02:15 +08:00
    @wddwycc 就像 @a412739861 说的一样,不是 contentInset 也不是 headerView ,而是两个平级 scrollView 和 tableView 。问题是如何将对 tableView 的手势传递到下一层的 ScrollView 中去?
    XDDD
        16
    XDDD  
       2016-05-19 19:21:43 +08:00
    @zhlooking 没那么复杂,只要把轮播盖在 tableView 上就行了
    xxppxiaowei
        17
    xxppxiaowei  
       2016-05-19 19:25:13 +08:00
    不知道 IOS 里面如何实现的。。 web 里面一般都是自己捕捉手势 判断下面那个 scrollview 到顶端的 offset
    a412739861
        18
    a412739861  
       2016-05-19 19:47:21 +08:00
    @zhlooking
    一开始禁用 tableview 的滚动,最底部的 scrollview 的 contentSize = self.view+header.height (高),判断 scrollViewDidScroll 的 contentoffset ,当滚动超过 headerview.height 的时候,让 tableView.scrollEnabled = YES,scrollView.scrollEnabled=NO 。可以有这种效果,但是不太流畅,在 scrollViewDidScroll 还有一些其他代码吧。

    不过特意写成这样,确定不是设计师故意折腾么?…………感觉能想到这效果然后让码农设计出来,也是够蛋疼的……
    zhlooking
        19
    zhlooking  
    OP
       2016-05-19 20:28:57 +08:00
    @XDDD 主要是 tableView 的 headerView 还有一个下拉刷新的控件,盖住的话,要通过 contentOffset 来改变轮播的位置,很蛋疼。
    @xxppxiaowei iOS 里面也有 offset 的。
    @a412739861 还要有下拉刷新和上拉刷新的控件,碎了一地……现在的方法是只使用一个 tableView ,设置 contentInset 的 top ,把轮播放在 tableView 里,在下拉刷新的时候通过 contentOffset 控制轮播的 originY 来显示下拉控件。不过和知乎的实现方式有差别。
    chenghuang
        20
    chenghuang  
       2016-05-19 20:36:12 +08:00
    完美实验。。。
    首先加一个 headerview 在 tableview 上,高度 0.然后假设上面的广告栏为 100 ,增加下面代码

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    CGRect rect = scrollView.frame;
    if (rect.origin.y > 0) {
    self.header.frame =CGRectMake(0, 0, self.view.bounds.size.width, scrollView.contentOffset.y);
    self.collectionView.tableHeaderView = self.header;
    scrollView.frame = CGRectMake(0, 100 - scrollView.contentOffset.y, self.view.bounds.size.width, self.view.bounds.size.height);
    }else{
    if (scrollView.contentOffset.y <= 100) {
    self.header.frame =CGRectMake(0, 0, self.view.bounds.size.width, scrollView.contentOffset.y);
    self.collectionView.tableHeaderView = self.header;
    scrollView.frame = CGRectMake(0, 100 - scrollView.contentOffset.y, self.view.bounds.size.width, self.view.bounds.size.height);
    }
    }
    }
    codeisjobs
        21
    codeisjobs  
       2016-05-19 20:44:28 +08:00 via iPhone
    我估计还是 scrollview 嵌套一个轮播和 tableview ,如何判断手势的话,根据需求监听响应者进行判断就行了
    zhlooking
        22
    zhlooking  
    OP
       2016-05-19 20:48:39 +08:00
    @chenghuang headerView 已经被下拉刷新的控件占了。现在用的做法是设置 contentInset ,再加一个 View 进去。
    XDDD
        23
    XDDD  
       2016-05-19 20:54:07 +08:00
    @zhlooking 移动轮播很麻烦吗?
    ```
    override func viewDidLoad() {
    super.viewDidLoad()
    tableView.contentInset = UIEdgeInsets(top: topView.frame.height, left: 0, bottom: 0, right: 0)
    tableView.scrollIndicatorInsets = UIEdgeInsets(top: topView.frame.height, left: 0, bottom: 0, right: 0)
    }

    func scrollViewDidScroll(scrollView: UIScrollView) {
    var rect = topView.frame
    let offset = -scrollView.contentOffset.y
    let topBarheight = self.navigationController?.navigationBar.frame.height ?? 0
    if offset < (topBarheight + rect.height) {
    rect.origin.y = offset - topView.frame.height
    } else {
    rect.origin.y = topBarheight
    }
    topView.frame = rect
    }
    ```

    知乎的实现方法好像不是这样(观察 Indicator 的位置),不过效果差别不大
    zhlooking
        24
    zhlooking  
    OP
       2016-05-19 21:00:40 +08:00
    @XDDD 谢谢 :)现在实现的就是这个方式。很好奇知乎到底是怎么搞得?
    cbf188
        25
    cbf188  
       2016-05-20 00:08:11 +08:00 via iPhone
    上知乎问问看(^_^)
    misaka15
        26
    misaka15  
       2016-05-20 15:02:00 +08:00
    @zhlooking 怎么可能? contentOffset.Y 能不变,不变我吃键盘。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2655 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 04:23 · PVG 12:23 · LAX 21:23 · JFK 00:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.