V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
WildCat
V2EX  ›  iDev

图文混排的贴子回复列表,适合用 UITableView 吗?图片异步加载后需要重新计算行高后如何重新渲染 UITableViewCell

  •  1
     
  •   WildCat · 2014-12-29 23:45:13 +08:00 · 10566 次点击
    这是一个创建于 3624 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在用 DTAttributedTextContentView (DTCoreText) 做图文混排,图片都是 lazy load 的,图片加载完成后,有个回调方法 - (void)lazyImageView:(DTLazyImageView *)lazyImageView didChangeImageSize:(CGSize)size ,这里可以获得图片的高度,或者重新计算 DTAttributedTextContentView 的高度。

    那么问题来了,图片加载后 DTAttributedTextContentView 的高度肯定会增加,这个 DTAttributedTextContentView 是在一个 UITableViewCell 里的,如何对它重绘?如果调用
    [tableview reloadRowsAtIndexPaths:[NSArray arrayWithObject: xxxIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic]
    这个方法,这个 cell 还是会被重新加载,高度还是重新计算,成为一个死循环。

    我在做的是 iOS8 only app, TableViewCell 用的是约束布局。 似乎调用 [cell setNeedsDisplay] 也是没效果的

    第 1 条附言  ·  2014-12-30 19:42:07 +08:00
    @Elethom
    @Daniel65536
    @wezzard
    @dcty
    @pljhonglu
    @dopcn
    @Hysteria

    我简单看了下了目前两个论坛客户端:威锋 和 NGA:


    
    
    这两个客户端都是传统的论坛,我抓包看过了,没有理想的带图片大小的 API。而且都是一个占位符(跟要加载的图片大小无关,就是为了表示这个位置会加载一个图片,图片加载完成后会调整)。但是情况远远没有各位想象的糟糕,因为如果某个贴子楼层已经拉到了屏幕上面,这个图片即使加载完成也不会显示(导致“蹦来蹦去”)。
    43 条回复    2016-01-27 09:13:06 +08:00
    kmvan
        1
    kmvan  
       2014-12-29 23:48:37 +08:00
    一直想问问,为啥ios开发和安卓开发里面的内置类或对象,都是驼峰命名?没有下划线命名吗?
    Elethom
        2
    Elethom  
       2014-12-30 00:11:07 +08:00 via iPhone   ❤️ 1
    圖片固定比例是 UI 設計的常識吧...
    WildCat
        3
    WildCat  
    OP
       2014-12-30 00:53:41 +08:00 via iPhone
    @Elethom
    问题是 V2EX 的图片附件这样的
    Daniel65536
        4
    Daniel65536  
       2014-12-30 01:37:26 +08:00   ❤️ 1
    不如固定显示成缩略图小正方形,提供一个点击查看大图的功能……?
    wezzard
        5
    wezzard  
       2014-12-30 03:46:19 +08:00   ❤️ 1
    你應該改變設計讓圖片的大小變成固定的,或者顯示多行圖像,但是每行的行高是固定的。

    即使 UITableView 能如你所說實現根據異步加載的內容動態調整尺寸,其所帶來的跳躍也是相當不友好的,尤其是在滾動中,用戶滾着滾着就丟失目前滾到哪的感知了。
    WildCat
        6
    WildCat  
    OP
       2014-12-30 08:08:22 +08:00 via iPhone
    @Daniel65536
    @wezzard
    @Elethom

    说下场景,就是 V2EX 客户端,帖子回复里的图片数量,大小和比例都不确定。如果缩略图固定比例肯定会非常难看,还是有必要动态调整的。
    目前这么做(动态调整)的就是威锋网客户端,但是不知道它是怎么实现的。


    @wezzard
    能否简单介绍下思路?谢谢!
    Elethom
        7
    Elethom  
       2014-12-30 08:10:22 +08:00
    @WildCat
    好一個 "肯定會"...
    dcty
        8
    dcty  
       2014-12-30 08:23:10 +08:00 via iPad   ❤️ 1
    @WildCat 接口中返回图片的高宽,本地计算合适的size,布局的时候直接用size。
    WildCat
        9
    WildCat  
    OP
       2014-12-30 08:26:57 +08:00 via iPhone
    @dcty V2EX 没有这样的接口啊
    WildCat
        10
    WildCat  
    OP
       2014-12-30 08:30:12 +08:00 via iPhone
    @Elethom

    您如果觉得我这个“肯定会”有问题请说原因。
    假如图片比例是 3:2 ,变成 1:1 必然不好看吧。
    pljhonglu
        11
    pljhonglu  
       2014-12-30 08:36:36 +08:00   ❤️ 1
    1.接口返回图片宽高,事先占位
    2.固定图片宽高
    zhigang1992
        12
    zhigang1992  
       2014-12-30 08:58:21 +08:00 via Android   ❤️ 1
    不需要,直接修改height delegat然后
    tableview.benginupdate
    tableview.endupdate
    zhigang1992
        13
    zhigang1992  
       2014-12-30 09:00:34 +08:00 via Android
    如果你使用的autolayout让iOS自己计算的话,用constraint把内容撑大就好了。
    dopcn
        14
    dopcn  
       2014-12-30 09:21:17 +08:00
    @kmvan 歪楼好惨,iOS 除非特殊情况没有下划线命名,因为 SDK 就是这么做的,为了写人能看懂的代码,跟着 SDK 走很必要。有一个特殊是C 语言宏名,是按 C 语言那种大写加下划线
    dopcn
        15
    dopcn  
       2014-12-30 09:33:12 +08:00   ❤️ 1
    图片异步加载常见的使用场景都是固定图片大小异步加载,如果异步加载后需要重新计算行高再 somehow 重新渲染 UITableViewCell,异步加载无法确定什么时候结束,如果还没结束你往下拉了,异步加载结束了tableView岂不是蹦来蹦去?

    方案1:前面有人提到了,用一个「图片」的图标做 placeholder,点击查看大图,这个方案也是我在做的公司项目的做法,还不错
    方案2:我自己做过一个类似论坛客户端用的方法是 UIWebView,勉强也可以实现图文混排,似乎算异步请求图片,效果就是上面说的蹦来蹦去
    LINAICAI
        16
    LINAICAI  
       2014-12-30 09:43:24 +08:00
    @kmvan 下划线一般用在变量和属性,对象和内置类都是驼峰命名
    LINAICAI
        17
    LINAICAI  
       2014-12-30 09:48:24 +08:00   ❤️ 1
    其实楼主这种方法貌似不现实啊,抛开解决方案难不说,其实这样的体验并非必须,15楼说的方案不错可以参考。
    按照楼主的需求,肯定不能只reload一行吧~
    cielpy
        18
    cielpy  
       2014-12-30 10:01:03 +08:00
    @zhigang1992 请教一下,如果有多个view的高度会变呢,比如说一个cell里的图片有标题,图片加载完成后知道高度,标题如果有多行则显示为多行,这个constraint该怎么设置呢。
    Hysteria
        19
    Hysteria  
       2014-12-30 10:17:10 +08:00
    @WildCat 我还是觉得移动端上采用图片行固定高度的方式好。图片采用等比缩放,始终不变形就还好吧。
    WildCat
        20
    WildCat  
    OP
       2014-12-30 10:20:47 +08:00 via iPhone
    @Hysteria 问题是,一层楼的图片数量也不确定
    zhigang1992
        21
    zhigang1992  
       2014-12-30 10:33:09 +08:00 via Android
    @cielpy 没说只能一条啊😃 如果是iOS8的话auto layout怎么用,他就怎么用。
    Hysteria
        22
    Hysteria  
       2014-12-30 13:04:23 +08:00
    @WildCat 这到也是啊。。。要不做成像微博客户端那种,把图片当做附件另外处理吧。
    hoogle
        23
    hoogle  
       2014-12-30 14:24:15 +08:00   ❤️ 1
    我写的时候通过读取缓存来避免循环 reload cell 的问题。 当然最好的是直接通过图片 URL 加入 hash 来取原始大小。。
    cielpy
        24
    cielpy  
       2014-12-30 15:06:40 +08:00
    @zhigang1992 两个高度可变的控件的constaint不知道怎么设置了。。
    yellowV2ex
        25
    yellowV2ex  
       2014-12-30 16:53:48 +08:00
    @kmvan 难道要跟php那么low吗?哈哈哈
    yellowV2ex
        26
    yellowV2ex  
       2014-12-30 16:57:17 +08:00   ❤️ 1
    @cielpy 我一般是弄一个 tempCell,然后 heightForCell 的时候把参数给这个temp然后返回temp的高度,虽然资源占用浪费了一点点,但方便啊,不用自己再去算一遍高。
    但这种做法不是最优,也比较浪费资源,正确的做法是,类似微信朋友圈,如果文字多过某个限定值,加一个显示更多。
    pubby
        27
    pubby  
       2014-12-30 17:02:43 +08:00
    @Hysteria 如果比例很夸张,高度固定后,宽度"超出"设备屏幕的怎么处理?
    此时:高度还是固定,但是图片居中并限制宽度?
    cielpy
        28
    cielpy  
       2014-12-30 18:43:27 +08:00
    @yellowV2ex 我做的不是评论这种的,是每个cell有图片,然后对图片有一个简单的介绍,在图片的下面,还有几个其他的控件,但是位置大小都固定。
    yellowV2ex
        29
    yellowV2ex  
       2014-12-30 19:17:41 +08:00
    @cielpy 实在要做的话,那就先给一个loading图片的高度,载入了之后,再reloaddata好了,然后把这个图片对应的高宽记下来,下次用
    yellowV2ex
        30
    yellowV2ex  
       2014-12-30 19:18:05 +08:00
    @cielpy 当然, 正确的做法是后台读到图片高宽传给你按比例计算
    hyzjshwo
        31
    hyzjshwo  
       2014-12-30 19:28:48 +08:00
    固定大小,如果动态是不是我上传一个1px * 800px的图 你app怎么玩?
    cielpy
        32
    cielpy  
       2014-12-30 19:36:55 +08:00
    @yellowV2ex 我用了autolayout,后台返回宽高比,我计算出图片应有的宽高,这个时候是可以知道图片的位置的,但是在storyboard里,这个imageView的contraint怎么设置呢。
    nathanw
        33
    nathanw  
       2014-12-30 20:05:59 +08:00   ❤️ 1
    可以参考一些微博客户端的做法
    yellowV2ex
        34
    yellowV2ex  
       2014-12-30 20:10:37 +08:00
    @cielpy 不好意思,autolayout不熟,你设置imageView下面的那堆东西相对于imageView的位置来自动位置,那么只需要设置 imageView frame 的 height,下面就应该会跟着变位置了吧。
    Elethom
        35
    Elethom  
       2014-12-30 20:33:49 +08:00 via iPhone   ❤️ 1
    @WildCat
    未經過排版就按原比例顯示很容易打破佈局, 比如說保持 aspect fill 寬度, 那我發一張 1x100 的小圖就可以刷屏了.
    WildCat
        36
    WildCat  
    OP
       2014-12-30 20:52:19 +08:00
    @Elethom 为什么总考虑极端呢?这种情况加个最大 height 限制不就可以了? 我主要是这种图文混排的实现,极端情况自然会考虑。
    Hysteria
        37
    Hysteria  
       2014-12-30 23:06:29 +08:00   ❤️ 1
    @pubby 这时候我倾向于宽度为设备宽度,重新等比例缩放。
    Hysteria
        38
    Hysteria  
       2014-12-30 23:09:59 +08:00
    @WildCat 效果确实没啥好大的问题。这两个客户端,好像都是取回图片之后,按照固定宽度,等比例缩放显示的。
    Esay
        39
    Esay  
       2014-12-31 00:25:25 +08:00   ❤️ 1
    按照自己的理解大致写了一下 https://github.com/Jeswang/load-cell-image

    太晚了,代码还有问题。没有 lazy load,用的是直接加载图片。如果 lazy load 的话,需要缓存一下图片,并且检查发起 lazy load 的 cell 是否可见(继承 DTLazyImageView,增加一个指向 cell 的引用)

    明天再改吧
    joeytat
        40
    joeytat  
       2015-02-11 17:00:30 +08:00   ❤️ 1
    没做过,但感觉可以实现。

    你先 lazy load,图片到了之后放进 NSTextAttachment 里面,然后扔进 NSAttributedString 里面实现图文混排。最后就可以用 textView.sizeThatFits: 来获得混排之后的高度了。

    有了高度之后 reload 一下 cell 就好了嘛。

    之前写过一个 NSAttributedString 图文混排的扩展,应该改改就能用。 https://github.com/joeytat/JTATEmoji
    wtgam
        41
    wtgam  
       2015-09-10 00:40:05 +08:00
    请问楼主这个问题解决了吗?请回复,我也遇到同样的问题,急,谢谢
    WildCat
        42
    WildCat  
    OP
       2015-09-10 07:24:12 +08:00 via iPhone
    @wtgam 没有解决。没有很符合需求的 rich text label ,目前尚无时间用 CoreText/TextKit 自己实现。
    暂时的解决办法:用一个 WebView
    cedared
        43
    cedared  
       2016-01-27 09:13:06 +08:00
    @WildCat 求问楼主这个问题现在有解决么?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1684 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 16:44 · PVG 00:44 · LAX 08:44 · JFK 11:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.