图文混排的贴子回复列表,适合用 UITableView 吗?图片异步加载后需要重新计算行高后如何重新渲染 UITableViewCell - V2EX
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 11000 次点击
    这是一个创建于 3943 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在用 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
        span class="no">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     Solana     3361 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 42ms UTC 04:43 PVG 12:43 LAX 21:43 JFK 00:43
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86