当前位置: 首页 > wzjs >正文

网站开发p6wordpress侧栏图片插件

网站开发p6,wordpress侧栏图片插件,两个女孩子怎么做网站,一个人建网站概览 在 SwiftUI 的世界里,我们无数次都梦想着视图可以自动根据布局上下文“因势而变”‌。大多数情况下,SwiftUI 会将每个视图尺寸处理的井井有条,不过在某些时候我们还是得亲力亲为。 如上图所示,无论顶部 TabView 容器里子视图…

在这里插入图片描述

概览

在 SwiftUI 的世界里,我们无数次都梦想着视图可以自动根据布局上下文“因势而变”‌。大多数情况下,SwiftUI 会将每个视图尺寸处理的井井有条,不过在某些时候我们还是得亲力亲为。

在这里插入图片描述

如上图所示,无论顶部 TabView 容器里子视图高度如何变化,TabView 本身的高度都能“随遇而安”。如何用最简单、最现代化、最有趣且最切中要害的方法让容器尺寸与子视图的高度“如影随形”呢?

在本篇博文中,您将学到如下内容:

  • 概览
  • 9. 最“相得益彰”的实现:自定义布局 Layout
    • 9.1 重装上阵 Layout
    • 9.2 “奇怪的” TabView
    • 9.3 MaxHeightLayout 的实现
  • 总结

相信学完本课后,小伙伴们必能脑洞大开、格局打开,用“千姿百态”的方法让问题的解决一发入魂、九转功成!

那还等什么呢?Let‘s go!!!😉


9. 最“相得益彰”的实现:自定义布局 Layout

在一口气介绍完上面 5 种“五花八门”的实现之后,我们完全可以“鸣金收兵”。但是为了面面俱到,我们最后还是决定用自定义布局 Layout 来为整个系列博文画一个圆满的句号。

9.1 重装上阵 Layout

所谓自定义布局 Layout,其实就是创建一款遵守 Layout 协议的“容器”(严格说应该是视图集合 Collection of views),然后“恣意”为内部的子视图“排兵布阵”:

在这里插入图片描述

为什么说用 Layout 这种方法更加“鞭辟入里”呢?因为这是处理多个同一层级子视图布局最自然的方式。

大家回忆一下:我们是将所有喜爱的成语用 ForEach 挨个放在 TabView 容器里的,在父容器中对它们的布局“运筹帷幄”是理所当然的事。


关于自定义布局的进一步介绍,请小伙伴们移步如下链接观赏精彩的文章:

  • SwiftUI 打造一款收缩自如的 HStack(四):Layout 自定义布局

9.2 “奇怪的” TabView

我们的目标是创建一个通用自定义布局 MaxHeightLayout,然后实时计算出所有子视图中最高的 Height。由于 MaxHeightLayout 是作为一个“容器”放在 TabView 中的,我们必须显式设置 TabView 的高度,而不能通过设置 MaxHeightLayout 的高度来间接影响 Tabview。

为什么会这样呢?这是由于 TabView 自身的特殊性质造成的。

比如在下面的代码中,我们在 TabView 里放置了一个高度为 200 的圆形:

TabView {Circle().foregroundStyle(.green.gradient).frame(height: 200)
}
.tabViewStyle(.page)

尽管我们将内部圆形的高度设置为 200,明确“暗示” TabView 把自己的高度也做出相应调整 ,但 TabView 还是会无动于衷:

在这里插入图片描述

要想 TabView 能够充分容纳高度为 200 的圆形,我们必须将 TabView 的高度显式设置为 200:

TabView {Circle().foregroundStyle(.green.gradient)
}
.tabViewStyle(.page)
.frame(height: 200)

在这里插入图片描述

换句话说,TabView 不会站在子视图的角度考虑问题,它会完全忽略子视图尺寸的提议,“一意孤行”。

9.3 MaxHeightLayout 的实现

上面讨论的结果迫使我们必须让自定义布局 MaxHeightLayout 想办法将计算产生的最大高度传递向外给 TabView 才行。

有很多种方法可以达到目的,这里我们采用最简单的一种:绑定(Binding)。

struct MaxHeightLayout: Layout {var spacing: CGFloat?@Binding var maxHeight: CGFloatfunc sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {let proposalWidth = proposal.width!let idealViewSizes = subviews.map { $0.sizeThatFits(.init(width: proposalWidth / CGFloat(subviews.count), height: nil)) }let totalHeight = idealViewSizes.map {$0.height}.max() ?? 0.0// 防止反复赋值造成渲染循环if totalHeight > maxHeight {maxHeight = totalHeight}return CGSize(width: proposalWidth, height: totalHeight)}private func calcSpaces(subviews: Subviews) -> [CGFloat] {if let spacing {[CGFloat](repeating: spacing, count: subviews.count - 1)} else {subviews.indices.map { idx inguard idx < subviews.count - 1 else { return 0 }return subviews[idx].spacing.distance(to: subviews[idx+1].spacing, along: .horizontal)}}}func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {let spaces = calcSpaces(subviews: subviews)var point = CGPoint(x: bounds.minX, y: bounds.minY)let subviewWidth = bounds.width / CGFloat(subviews.count)for idx in subviews.indices {subviews[idx].place(at: point, proposal: .init(width: subviewWidth - spaces[idx], height: maxHeight))if idx < subviews.count - 1 {point.x += subviewWidth - spaces[idx]}}}    
}

在上面的代码中,我们主要做了这么几件事:

  • 让 MaxHeightLayout “容器”中每个子视图的宽都平分容器的宽度;
  • 用 calcSpaces 方法计算子视图间的空隙,并确保 placeSubviews 方法在布局子视图时应用它们;
  • 只在必要时更新 maxHeight 绑定的值(totalHeight > maxHeight 时),这是避免“递归渲染”的重要手段;

最后,只要将 TabView 中原来内层的 ForEach 循环以及相关逻辑放在 MaxHeightLayout 里就可以啦:

Section("喜爱的成语") {TabView {ForEach(likeIdioms.chunked(into: 2), id: \.self) { idiomChunk inVStack {MaxHeightLayout(maxHeight: $maxHeight) {                    ForEach(idiomChunk) { idiom inlikeIdiomCard(idiom)}if idiomChunk.count < 2 {Rectangle().foregroundStyle(.clear)}}Spacer()}}}.tabViewStyle(.page).frame(height: maxHeight).padding(.bottom, 8)
}

运行代码可以发现结果和其它的实现毫无二致!

在这里插入图片描述

借助自定义布局 Layout 的灵活性,我们可以非常轻松的改变 TabView 中成语显示的数量,比如改为 3 列也不在话下:

在这里插入图片描述

至此,我们圆满完成了本系列博文中的所有任务。秃头小伙伴们还不赶紧给自己一个大大的赞吧!爱你们哦!❤


想要进一步系统地学习 Swift 开发的小伙伴们,可以来我的《Swift 语言开发精讲》专栏逛一逛哦:

在这里插入图片描述

  • 《Swift 语言开发精讲》

总结

在本篇博文中,我们介绍了如何使用自定义布局 Layout 来实现 SwiftUI 视图高度的“遥相呼应”,精彩的大结局小伙伴们不容错过哦!

感谢观赏,再会啦!😎


文章转载自:

http://dqxLyOea.cjwkf.cn
http://iPWJv8zM.cjwkf.cn
http://VdS9oiKY.cjwkf.cn
http://wWkitlee.cjwkf.cn
http://3V07U599.cjwkf.cn
http://JjaZa8At.cjwkf.cn
http://MGgNZeI1.cjwkf.cn
http://7fEm0QB4.cjwkf.cn
http://uFsT3ZSo.cjwkf.cn
http://usFz2ki5.cjwkf.cn
http://6TBC1ugi.cjwkf.cn
http://eiwE0yQK.cjwkf.cn
http://fk3MNkiA.cjwkf.cn
http://Nvx80AkH.cjwkf.cn
http://QXvnSL34.cjwkf.cn
http://FVDuMJ8e.cjwkf.cn
http://fZMBgDkC.cjwkf.cn
http://GO9KKRAH.cjwkf.cn
http://R4xxlttB.cjwkf.cn
http://03P0dTwO.cjwkf.cn
http://DcwNeHoX.cjwkf.cn
http://46qJS8C8.cjwkf.cn
http://CiPrHINs.cjwkf.cn
http://HHUeW0BE.cjwkf.cn
http://XsHzcPXw.cjwkf.cn
http://tsY9JGVL.cjwkf.cn
http://lUHLgAO2.cjwkf.cn
http://tkKAtR1Q.cjwkf.cn
http://7xyTZ29t.cjwkf.cn
http://tYjcI9WU.cjwkf.cn
http://www.dtcms.com/wzjs/713243.html

相关文章:

  • wordpress网站管理员插件榆林北京网站建设
  • seo网站推广佛山网站推广的一般方式
  • 校园网站建设特色视觉传达设计是学什么的
  • 工程建设项目网站漯河专业做网站的公司
  • 汕头建站程序软文标题写作技巧
  • 龙岩找工作网站网站优化潍坊
  • 网页游戏推广网站怎么做html5响应式网站模板
  • 广州培训网站开发西安seo排名收费
  • 企业需要做网站吗建设网站注意事项
  • 丫个网站建设网页设计和制作的三大步骤
  • 怎么看一个网站做的好不好网页制作创建站点
  • 手机做网站用什么应届生求职网站官网
  • 深圳手机端网站建设模板dw网页制作多少钱
  • 中文免费网站模板upscale wordpress
  • 微网站开发报价手机制作海报的软件免费
  • 网站建设需要用到什么软件有哪些建筑网站建设赏析
  • 网站技术建设方案网站百度排名提升
  • 安徽网站建设哪家有建设银行鄂州分行官方网站
  • 手机怎么自己创造网站个人动漫网站怎么做页面
  • 指定网站建设项目规划书wordpress改了ip
  • 可不可以自己做网站企业采购平台哪个好
  • akm建站系统友点企业网站模板下载
  • 地产建站规划如何免费做网页
  • 自己买服务器做网站网站统计源码
  • 湛江廉江网站建设网站授权书
  • 定制网站建设官网中国10大品牌网官网
  • 网站下面 备案室内设计联盟课堂
  • 浙江省住房和城乡建设厅 官方网站wordpress加载中
  • 晾衣架 东莞网站建设广州建设总承包集团
  • 西安网站快速优化南宁网页设计培训机构