UIStackView的基於功能組織程式碼拆分的一些猜想
所有的最初,都來源於偉大的理想,和一時發熱的頭腦。想法不一定對,但卻是一個方向,希望各位小夥伴一起探討,相互交流,能指點一二,不勝感激。
比心
首先說一下UIStackView是個什麼東西
UIStackView看字面意思,就是在UIView中插入了一個Stack, Stack是什麼意思了,查下字典,“堆疊,排列”, 沒錯,UIStackView就是用來排列其它子View的容器,而且這個排列是線性的,什麼意思?也就是說要麼橫向排列,要麼縱向排列,你不能橫縱交替,但是我們可以進行巢狀的使用來達到一些縱橫交替的效果。
UIStackView使用屬性和方法說明
//構造方法,views為需要排列到StackView中的子Views
public init(arrangedSubviewsviews: [UIView])
//返回StackView中裝入的Views
public var arrangedSubviews:[UIView] { get }
//往StackView中裝入一個View
public func addArrangedSubview(view: UIView)
//從StackView中移除一個View
public func removeArrangedSubview(view: UIView)
//插入一個View到指定的Index
public func insertArrangedSubview(view: UIView, atIndexstackIndex: Int)
//設定排列方向,橫向還是縱向,預設是橫向
public var axis: UILayoutConstraintAxis
//屬性決定了其管理的檢視在沿著其軸向上的佈局
public var distribution: UIStackViewDistribution
//(對齊)屬性決定了其管理的檢視在垂直於其軸向上的佈局;比如Center居中對齊, Fill,填滿, Leading,起點對齊等。
public var alignment: UIStackViewAlignment
//設定每個View間的間距,如果是橫向排列的話,就是橫向間距,縱向的話,就是縱向間距。
public var spacing: CGFloat
public var baselineRelativeArrangement: Bool
public var layoutMarginsRelativeArrangement: Bool
猜想
- 首先我們要針對我們的場景,對於我們的一些控制器裡可能會涵蓋很多的功能模組點,比如說在首頁的展示中我們會有 Banner輪播圖,Icon圖示表,最新內容展示區,最熱內容展示區,視訊功能區,音訊功能區,列表功能區等等。諸如此類的功能量,都放到我們的一個控制器中,可想而知我的程式碼量以及耦合度。不論是前期開發還是後期維護都是非常不便。今天我們猜想一下一個可行的解決方案,當然也是會有別的解決方案的,這次只是介紹這個與UIStackView相關的一個解決方案的猜想。
我們把每個功能點的組織程式碼分別拆分到單獨的子控制器當中,把業務分散,只把控制權放在當前主題介面。
UIStackView如何結合UIScrollView使用?
對於介面,滑動功能一般是必不可少的。
UIStackView沒有自帶scrollView的,那就只能用自已結合ScrollView來實現了。好吧,其實實現也很簡單,首先建立一個scrollView,然後把stackView放到scrollView中去就可以了,當然要使其滑動,需要正確設定scrollView的contentSize,描述就是這樣的。
上程式碼:
import UIKit
class ViewController: UIViewController {
var scrollView: UIScrollView?
var stackView: UIStackView?
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
setUI()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView?.contentSize = CGSize(width: (stackView?.frame.width)!, height: (stackView?.frame.height)!)
print(scrollView?.contentSize.height ?? 0)
}
}
extension ViewController {
fileprivate func setUI() {
scrollView = UIScrollView()
view.addSubview(scrollView!)
scrollView?.snp.makeConstraints({ (make) in
make.edges.equalTo(self.view)
})
// 重新整理
scrollView?.mj_header = MJRefreshNormalHeader(refreshingTarget: self, refreshingAction: #selector(ViewController.loadData))
scrollView?.mj_footer = MJRefreshBackFooter(refreshingTarget: self, refreshingAction: #selector(ViewController.loadMoreData))
stackView = UIStackView()
stackView?.axis = .vertical
stackView?.spacing = 10
scrollView?.addSubview(stackView!)
stackView?.snp.makeConstraints({ (make) in
make.top.equalTo(self.scrollView!)
make.left.equalTo(self.scrollView!)
make.right.equalTo(self.scrollView!)
make.width.equalTo(self.scrollView!)
make.bottom.equalTo(self.scrollView!)
})
setChildVC()
}
// 控制器
fileprivate func setChildVC() {
addVC(BannerVC())
addVC(NewIconVC())
addVC(AudioVC())
addVC(VideoVC())
addVC(ListVC())
}
// 載入控制器
fileprivate func addVC(_ vc: HomeBaseVC) {
self.addChildViewController(vc)
self.stackView!.addArrangedSubview(vc.view)//將vc.view放於stackView容器中,此後不需要設定vc.view的任何約束,就能實現從上到下排列顯示,寬高都是自適應大小,注意這兒必須要用addArrangedSubview而不能用addSubView
vc.homeDelegate = self
}
// 模擬重新整理
@objc fileprivate func loadData() {
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 2) {
DispatchQueue.main.async {
self.scrollView?.mj_header.endRefreshing()
//清空stackView中的 subView
if let arrangedSubviews = self.stackView?.arrangedSubviews {
for subView in arrangedSubviews {
self.stackView?.removeArrangedSubview(subView)
}
}
// 刪除子控制器
for childVC in self.childViewControllers {
childVC.removeFromParentViewController()
}
// 重新載入
self.setChildVC()
}
}
}
// 模擬載入更多
@objc fileprivate func loadMoreData() {
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 2) {
DispatchQueue.main.async {
self.scrollView?.mj_footer.endRefreshing()
self.scrollView?.mj_footer.endRefreshingWithNoMoreData()
self.addVC(ListVC())
}
}
}
}
extension ViewController: UPdataContainsDelegate {
// 根據控制器回撥設定約束高度
func upDataContains( _ childVC: HomeBaseVC, _ containHeight: CGFloat) {
// childVC.view.frame = CGRect(x: 0, y: 0, width: kSCREEN_WIDTH, height: 200) //不用設FRAME了,設了也不會起作用的,因為stackView會自動去新增一些約束。
childVC.view.snp.makeConstraints { (make) in
make.height.equalTo(containHeight)
}
}
}
實現當中我覺得是有很多不合理的地方,希望各位小夥伴們有好的方法方案,一定要點撥一二哦。☺ 加油共勉。
相關文章
- 基於Vue的組織架構樹元件Vue架構元件
- 組織css程式碼CSS
- 程式碼模型組織方式模型
- objective-C 的程式碼檔案組織Object
- 我們正在錯誤的組織程式碼!
- .NET C#基礎(6):名稱空間 - 組織程式碼的利器C#
- Go包-程式碼組織者Go
- 基於知識圖譜的APT組織追蹤治理APT
- 如何組織軟體模組的程式碼結構?
- 公司程式碼與採購組織的關係
- 如何組織大型JavaScript應用中的程式碼?JavaScript
- 建立適於敏捷的組織文化敏捷
- 如何組織大型 Rust 程式碼庫Rust
- ModStartCMS 基於 Laravel 模組化組織的後臺系統框架Laravel框架
- 從事件系統說起,更好的組織程式碼事件
- 程式的定義、組成、組織方式、特徵特徵
- JavaScript程式碼組織結構良好的5個特點JavaScript
- 關於程式碼的一些思考
- 計算機程式的思維邏輯 (22) - 程式碼的組織機制計算機
- SAP MM 採購組織和公司程式碼的分配關係
- 用BEM命名規範組織CSS程式碼CSS
- 前端程式碼拆分前端
- 基於上下文感知計算的APT攻擊組織追蹤方法APT
- 人生如解 -- 關於破解組織的亂彈
- Oracle堆組織表的索引和索引組織表Oracle索引
- 記錄一些科學家和組織
- 重構-改善既有程式碼的設計(六)–重新組織函式函式
- 組織的紀律
- 對騰訊後續“組局”遊戲直播的猜想遊戲
- 組織程式和資料
- 以歐洲組織為目標的基於python的惡意軟體家族PWOBotPython
- 關於如何時空旅行的猜想
- webpack之程式碼拆分Web
- 【功能外掛】基於 Laravel 開發的小程式登陸功能Laravel
- [功能外掛] 基於 Laravel 開發的小程式登陸功能Laravel
- 組織知識的方法
- 系統的模組組織
- 企業IT組織的治理