草庐IT

ios - 适用于 iOS 的自调整单元格和动态大小控件

coder 2023-07-28 原文

问题定义

我正在尝试构建一个行为类似于 UILabel 的自定义控件。我应该能够将这样的控件放置在一个自动调整大小的表格单元格中,它应该:

  • 包装它的内容(就像 numberOfLines=0 的 UILabel 那样)
  • 自动扩展自调整单元格高度尺寸
  • 处理设备旋转
  • 不需要 UITableCellView 或 ViewControll 中的任何特殊代码来实现此功能(UILabel 不需要任何特殊代码)。

研究

我做的第一件事非常简单。我决定观察 UILabel 是如何工作的。我做了以下操作:

  • 创建了一个包含自动调整单元格大小的表格
  • 创建了一个自定义单元格,将 UILabel(numberOfLines=0) 放入其中
  • 创建约束以确保 UILabel 占据整个单元格
  • 子类化 UILabel 并重写一堆方法以查看它的行为

我检查了以下内容

  • 纵向运行(标签在多行中正确显示)并且单元格高度正确
  • 旋转它。表格宽度和高度已更新,它们也是正确的。

我观察到它表现良好。它不需要任何特殊代码,我看到了系统渲染它的(一些)调用顺序。

部分解决方案

@Wingzero 在下面写了一个部分解决方案。它创建正确大小的单元格。

但是,他的解决方案有两个问题:

  • 它使用“self.superview.bounds.size.width”。如果您的控件占据整个单元格,则可以使用它。但是,如果您在使用约束的单元格中有任何其他内容,那么此类代码将无法正确计算宽度。

  • 它根本不处理旋转。我很确定它不会处理其他调整大小事件(有一些不太常见的调整大小事件——比如状态栏在电话中变大等)。

你知道如何解决这个案例的这些问题吗? 我发现了一堆文章,这些文章讨论了构建更多静态自定义控件以及在自调整单元格中使用预构建控件。

但是,我还没有找到任何可以组合处理这两个问题的解决方案。

最佳答案

我必须使用答案部分来发布我的想法并继续前进,尽管这可能不是你的答案,因为我不完全理解是什么阻碍了你,因为我认为你已经知道内在的大小,仅此而已。

根据评论,我尝试创建一个带有文本属性的 View 并覆盖内在属性:

头文件,后来发现maxPreferredWidth完全没有用到,就忽略了:

@interface LabelView : UIView

IB_DESIGNABLE
@property (nonatomic, copy) IBInspectable NSString *text;
@property (nonatomic, assign) IBInspectable CGFloat maxPreferredWidth;

@end

.m文件:

#import "LabelView.h"

@implementation LabelView

-(void)setText:(NSString *)text {
    if (![_text isEqualToString:text]) {
        _text = text;
        [self invalidateIntrinsicContentSize];
    }
}

-(CGSize)intrinsicContentSize {
    CGRect boundingRect = [self.text boundingRectWithSize:CGSizeMake(self.superview.bounds.size.width, CGFLOAT_MAX)
                                           options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading
                                        attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16]}
                                           context:nil];
    return boundingRect.size;
}

@end

和一个带有 xib 的 UITableViewCell:

头文件:

@interface LabelCell : UITableViewCell

@property (weak, nonatomic) IBOutlet LabelView *labelView;

@end

.m文件:

@implementation LabelCell

- (void)awakeFromNib {
    [super awakeFromNib];
}

@end

xib,很简单,就是top, bottom, leading, trailing约束:

所以运行它,基于文本的边界矩形,单元格的高度是不同的,在我的例子中,我有两个文本要循环:1.“哈哈”,2.“asdf”{重复多次以创建一个长字符串

所以奇数单元格的高度为 19,偶数单元格的高度为 58:

这是你要找的吗?

我的想法:

UITableView 的单元格宽度始终与表格 View 相同,所以这就是宽度。 UICollectionView 可能有更多问题,但关键是我们会计算它并返回它就足够了。

演示项目:https://github.com/liuxuan30/StackOverflow-DynamicSize
(我根据我的旧项目进行了更改,其中有一些图像,请忽略这些。)

关于ios - 适用于 iOS 的自调整单元格和动态大小控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35712724/

有关ios - 适用于 iOS 的自调整单元格和动态大小控件的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  3. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  4. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  5. ruby - inverse_of 是否适用于 has_many? - 2

    当我使用has_one时,它​​工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290

  6. ruby-on-rails - Prawn - 表格单元格内的链接 - 2

    我正在尝试用Prawn生成PDF。在我的PDF模板中,我有带单元格的表格。在其中一个单元格中,我有一个电子邮件地址:cell_email=pdf.make_cell(:content=>booking.user_email,:border_width=>0)我想让电子邮件链接到“mailto”链接。我知道我可以这样链接:pdf.formatted_text([{:text=>booking.user_email,:link=>"mailto:#{booking.user_email}"}])但是将这两行组合起来(将格式化文本作为内容)不起作用:cell_email=pdf.make_c

  7. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  8. ruby - 在 Ruby 中动态创建数组 - 2

    有没有办法在Ruby中动态创建数组?例如,假设我想遍历用户输入的书籍数组:books=gets.chomp用户输入:"TheGreatGatsby,CrimeandPunishment,Dracula,Fahrenheit451,PrideandPrejudice,SenseandSensibility,Slaughterhouse-Five,TheAdventuresofHuckleberryFinn"我把它变成一个数组:books_array=books.split(",")现在,对于用户输入的每一本书,我想用Ruby创建一个数组。伪代码来做到这一点:x=0books_array.

  9. ruby - 单元测试文件 I/O 方法 - 2

    我对单元测试还是比较陌生。我用Ruby编写了一个类,它接受一个文件,在该文件中搜索给定的Regex模式,替换它,然后将更改保存回文件。我希望能够为此方法编写单元测试,但我不知道我将如何去做。有人能告诉我我们如何对处理文件i/o的方法进行单元测试吗? 最佳答案 看看这个HowdoIunit-testsavingfiletothedisk?基本上这个想法是一样的,文件系统是你的类的依赖。所以引入一个可以在你的单元测试中模拟的角色/接口(interface)(这样你在单元测试时就没有依赖性);角色中的方法应该是您从文件系统中需要的所有东西

  10. ruby - 是否可以将 IRB 提示配置为动态更改? - 2

    我想在IRB中浏览文件系统并让提示更改以反射(reflect)当前工作目录,但我不知道如何在每个命令后进行提示更新。最终,我想在日常工作中更多地使用IRB,让bash溜走。我在我的.irbrc中试过这个:require'fileutils'includeFileUtilsIRB.conf[:PROMPT][:CUSTOM]={:PROMPT_N=>"\e[1m:\e[m",:PROMPT_I=>"\e[1m#{pwd}>\e[m",:PROMPT_S=>"FOO",:PROMPT_C=>"\e[1m#{pwd}>\e[m",:RETURN=>""}IRB.conf[:PROMPT_MO

随机推荐