背景
我正在制作一个垂直标签,用于传统的蒙古文字.在我刚刚轮换之前,UILabel但是有一些性能问题和其他复杂问题.现在我正在努力从头开始制作标签.但是,当高度调整时(基于字符串长度),我需要垂直标签来告诉自动布局.
我读过的
我阅读了内在内容大小和视图与内在内容大小文档.但这些更多是关于如何使用它,而不是如何在自定义视图中定义它.
搜索"自定义视图的ios内在大小"只能给我
在Stack Overflow中.这个特殊问题甚至不需要内在的内容大小,因为它们的视图只是标准视图的集合.
我在想什么
我正在尝试的是下面的答案.我正在添加这个Q&A对,这样就不会花费其他人那么长的时间来找到答案,因为它使用了我使用的搜索关键字.
我最近又开始使用Swift进入iOS开发,现在我正在研究定制的UIControl.对于布局和灵活性,此自定义视图使用StackView构建.
...基本上只是具有与StackView相同的功能,当我将它直接拖到故事板中时我通常拥有它 - 它调整大小以适应没有问题.这与自我调整tableview单元基本相同.
我可以将我的CustomView简化为一个简单的例子:它是一个包含三个标签的StackView,Alignment设置为Center,Distribution Equal Centering.StackView将固定到左,右和顶部布局指南(或尾随,前导和顶部).我可以轻松地使用CustomView重新创建,从XIB加载转换为具有相同参数的CustomView - 我将两者作为屏幕截图附加.
import UIKit
@IBDesignable
class CustomView: UIView {
// loaded from NIB
private weak var view: UIView!
convenience init() {
self.init(frame: CGRect())
}
override init(frame: CGRect) {
super.init(frame: frame)
self.loadNib()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.loadNib()
}
override func layoutSubviews() {
super.layoutSubviews()
// we need to adjust the frame of the subview to no longer match the …Run Code Online (Sandbox Code Playgroud) 我基本上试图重现警报的标题和消息部分的行为.
标题和消息标签似乎位于滚动视图中.如果标签文本增加,则警报高度也随着标签的固有内容大小而增加.但在某个高度,警报高度停止增加,标题和消息文本变为可滚动.
我读过的内容:
用品
堆栈溢出
答案可能在那里,但我无法抽象它.
我尝试过的:
我只关注具有两个标签的滚动视图,我试图做一个最小的例子,其中父视图将根据scrollview的内在高度调整大小.我玩过很多限制.这是一个组合(许多)组合不起作用:
我使用过自动布局和正常约束,甚至内在的内容大小.此外,我知道如何使用自动布局获得基本滚动视图.但是,我从未做过任何关于优先级和内容拥抱以及抗压缩性的事情.从我所做的阅读中,我对它们的含义有一种肤浅的理解,但我不知道如何在这种情况下应用它们.我的猜测是我需要对内容拥抱和优先级做些什么.
在我的下面的代码中:我在垂直scrollView中添加了5个按钮.每个按钮都被约束到scrollViews的顶部+20,前导,后缘及其高度.我创建了一个b1HeightConstraint变量.它是按住b1按钮的heightConstraint .
在按钮单击中,我正在尝试删除此约束.然而,我面临一个奇怪的问题:
当我记录约束时,我只看到2个约束,即使我已经添加了4个约束.我的视图调试层次结构如下所示:
import UIKit
import Foundation
class ViewController: UIViewController {
var filterView: UIView!
var scrollView: UIScrollView!
var containerView: UIView!
override func loadView() {
filterView = UIView()
view = filterView
view.backgroundColor = #colorLiteral(red: 0.909803926944733, green: 0.47843137383461, blue: 0.643137276172638, alpha: 1.0)
scrollView = UIScrollView()
scrollView.backgroundColor = #colorLiteral(red: 0.474509805440903, green: 0.839215695858002, blue: 0.976470589637756, alpha: 1.0)
view.addSubview(scrollView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
scrollView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 1).isActive …Run Code Online (Sandbox Code Playgroud) 当我在SwiftUI中创建视图并在Xcode预览中使用渲染时PreviewLayout.sizeThatFits,预览会根据其内容调整其大小。当我使用导入UIKIt视图时UIViewRepresentable,它会显示完整的设备尺寸框架。
有没有一种方法,使SwiftUI尊重intrinsicContentSize的UIView子类?
struct Label: UIViewRepresentable {
func makeUIView(context: UIViewRepresentableContext<Label>) -> UILabel {
return UILabel()
}
func updateUIView(_ uiView: UILabel, context: UIViewRepresentableContext<Label>) {
uiView.text = "Some text"
}
}
#if DEBUG
struct Label_Previews: PreviewProvider {
static var previews: some View {
Group {
Label().previewLayout(.sizeThatFits)
}
}
}
#endif
Run Code Online (Sandbox Code Playgroud) 我正在使用自定义布局UICollectionView.我的牢房应该有固定的宽度和灵活的高度.
细胞由a UImageView和a 组成UIStackView.本UIImageView的限制如下:
image.top = cell.top
image.width = cell.width
image.height = image.width * 1.33
image.centerX = cell.centerX
image.bottom = stackView.top
Run Code Online (Sandbox Code Playgroud)
堆栈视图类似,并且确实绑定到单元格的底部.
当系统正在呼叫时 preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
我正在进行一些计算以获得细胞的高度.
let preferredAttributes = super.preferredLayoutAttributesFitting(layoutAttributes)
let size = CGSize(width: layoutAttributes.frame.width,
height: UILayoutFittingCompressedSize.height)
let preferredSize = systemLayoutSizeFitting(size,
withHorizontalFittingPriority: .defaultHigh,
verticalFittingPriority: .fittingSizeLevel)
Run Code Online (Sandbox Code Playgroud)
事实证明,preferredSize是使用imageView内在大小而不是遵守约束来计算的.因此,对于具有850x850的图像(以及160个宽度的单元格),我的高度比我预期的要高得多,因此底部有一个巨大空间的单元格.
我设法解决了这个问题,我觉得这是一个黑客攻击.
我创建了对图像宽度约束的引用,当我使用从layoutAttributes获得的固定值调用此方法并调用setNeedsLayout()和layoutIfNeeded()时更新它,这是有效的.但我真的不喜欢我必须再次强制布局并自己更新宽度,更不用说我的性能松动了.
如何以更好的方式完成?
非常感谢你.
我UITableView跟UITableViewAutomaticDimension一些estimatedRowHeight。对于此表,我正在使用custom UITableViewCell,其中包含一些标签和custom UIView和overridden intrinsicContentSize()。约束设置正确,表格可以确定每行的实际高度。到目前为止,一切都很好。
现在,我开始根据可用宽度修改自定义视图的内部逻辑,以适应其外观,即,当表格单元格大小不够宽时,我的视图可以重新排列子视图以适应新的限制,这会影响最终的高度,所以我有如下代码那:
var internalSize: CGSize = ...
override func intrinsicContentSize() -> CGSize {
return internalSize
}
override func layoutSubviews() {
super.layoutSubviews()
fitIntoWidth(frame.size.width)
}
private func fitIntoWidth(width: CGFloat) {
let height = // calculate based on content and width
internalSize = CGSizeMake(width, height)
invalidateIntrinsicContentSize()
}
Run Code Online (Sandbox Code Playgroud)
现在,当我填充表格视图时,intrinsicContentSize()返回一些所需的值,但它不适用于当前布局,然后控制转到layoutSubviews()重新计算大小并再次调用系统的位置intrinsicContentSize(),现在它返回良好的值。但是,第一次时间表会加载基于错误intrinsicContentSize()值计算的数据和像元高度。如果我再打reloadData()一次,一切都会变好,并且表格中所有后续单元格的布局也都可以。
我的错误在哪里,以及如何修改代码以使单元大小正确工作而无需调用reloadData()两次?
uitableview ios swift uitableviewautomaticdimension intrinsic-content-size
我一直认为你可以指定一个<img/>'swidth和height属性,这样浏览器就知道它的物理尺寸,而不必先下载(至少是标题)。但显然这些属性被视为 CSS 属性 - 因此当您尝试执行类似width: 50%; height: auto. 然后,在下载图像之前,计算的高度保持为 0。
有没有办法通过 HTML/CSS 显式设置图像的物理尺寸(实际上是它的纵横比)?
(...并避免“未知长宽比的闪光”/使用 Masonry 时要进行大量紧张的重新布局 - 您也许可以解决这个问题,但我对基本问题更感兴趣。即使我正在努力询问简明扼要地介绍一下:)
我正在尝试使用自动布局对齐两个 UILabel,其中第一个标签没有设置宽度,但使用内部内容大小,第二个标签应与第一个标签的宽度相同,将文本换行到新行。
理想情况下,第二个标签应该将数字线设置为0与动态类型一起使用,但我2暂时将其设置为,甚至给了它一个特定的高度。然而,当我尝试对齐equal widths或 时trailing,内在内容大小标签扩展到多行标签的宽度,就好像它都在一行上一样(见下图)。
有什么方法可以让我在不指定第一个标签的宽度的情况下实现我想要的?我希望它扩展内容以考虑动态类型,并且第二个标签具有相同的宽度并将所有文本换行到新行。
我不知道为什么设计能够适应其内容的单元格如此复杂。它不应该需要那么多代码,我仍然不明白为什么UIKit不能正确处理这个问题。
无论如何,这是我的问题(我已经编辑了整篇文章):
我有一个UICollectionViewCell包含UITableView.
这是我的sizeForItem方法:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
var cellWidth: CGFloat = collectionView.bounds.size.width
var cellHeight: CGFloat = 0
let cellConfigurator = items[indexPath.item].cellConfigurator
if type(of: cellConfigurator).reuseId == "MoonCollectionViewCell" {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: type(of: cellConfigurator).reuseId, for: indexPath) as? MoonCollectionViewCell {
cell.contentView.layoutIfNeeded()
let size = cell.selfSizedTableView.intrinsicContentSize
cellHeight = size.height
}
}
return CGSize.init(width: cellWidth, height: cellHeight)
}
Run Code Online (Sandbox Code Playgroud)
sizeForItem之前调用过cellForItem …
uitableview ios uicollectionviewcell swift intrinsic-content-size
我在水平 纸中嵌入了两个标签UIStackView。标签之一可能会变得太大,因此其中一个被截断了。
或者,它们的大小正在按一定比例分割,并且垂直增长。
我要实现的目标是,如果标签不合适,请UIStackView更改axis为垂直。
请参考以下两个数字:
图1:标签排成一行,使用水平轴。
图2:标签之一是多行。使用垂直轴。
使用UICollectionViewFlowLayout时,行为类似。
我想了解为什么宽度指定为“ max-content ”的父 Flex 容器的宽度与单独的不灵活子 Flex 项目的宽度不同。
根据我对 Flexbox内在尺寸规范的理解,子级具有正确的宽度,但父级不尊重子级的主尺寸最大内容贡献。
这是 JSFiddle: https: //jsfiddle.net/c0f5xwn0/
<div style="width:max-content; display:flex;border:1px green solid;">
<div style="height:100px; flex:0 0 100px; border:1px red solid; width:200px">Why parent div has more width than child?</div>
</div>
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下这背后的原因吗?
ios ×9
autolayout ×5
swift ×5
css ×2
uistackview ×2
uitableview ×2
flexbox ×1
html ×1
image ×1
swiftui ×1
uilabel ×1
uiscrollview ×1
uitableviewautomaticdimension ×1
xcode ×1
xcode11 ×1
xib ×1