ComplicatedUIAndMutiRequestDemo
This project is a multi-layer complex structure and multi request interface implementation case.
No, please advise.
Thank you:)
explain:
The interface layout of this project is mainly Moya selected by IGListKit for network request.
Overview
Requirements
- Xcode 9.0+
- iOS 9.0+
- Swift 4.0+
- CocoaPods
Example
class DemoViewController: RootListViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. configData() } func configData() { listManager.removeAll() let gridOne = CollectionManager("gridOne", request: Home.gridItem) { () -> ListSectionController in return self.gridSectionController() } let textOne = CollectionManager("textOne", request: Home.text) { () -> ListSectionController in return self.textSectionController() } let imageOne = CollectionManager("imageOne", request: Home.image) { () -> ListSectionController in return self.imageSectionController() } let centerTextOne = CollectionManager("centerTextOne", request: Home.centerText) { () -> ListSectionController in return self.embeddedSectionController() } listManager.register([gridOne, textOne, centerTextOne, imageOne]) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }
Content of project framework:
-
RootListdViewController: the core ViewController from which any other extension instance can inherit
import IGListKit import Moya open class RootListViewController: UIViewController { ///IGListKit needs to use lazy var adapter: ListAdapter = { return ListAdapter(updater: ListAdapterUpdater(), viewController: self, workingRangeSize: 1) }() ///Display layout @IBOutlet public var collectionView: UICollectionView! ///Data configuration tool lazy var listManager: ListManager = { return ListManager(Date().description, delegate: self) }() override open func viewDidLoad() { super.viewDidLoad() if collectionView == nil { collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) } if collectionView.superview == nil { view.addSubview(collectionView) } adapter.collectionView = collectionView adapter.dataSource = listManager } override open func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() collectionView.frame = view.bounds } } extension RootListViewController: UpdateData { func dataUpdated() { self.adapter.performUpdates(animated: true, completion: nil) } }
ListManager manages all display items in the current interface
Collection Manager: contains each group of elements that need to be displayed. Listmanager's_ Value in itemKeyValues.
final class CollectionManager { ///What needs to be done after configuration is completed, not used at present var completion: ((CollectionManager) -> Void) = { _ in } ///Contained elements var items: [ListDiffable] = [] ///Unique identifier of my ListManager var listManagerIdentifier: String = "" ///My unique identifier var identifier: String = "" ///Start request data var startRequest = true ///Request type public var request: Home = .none weak var delegate: UpdateData? init(_ identifier: String, request: Home = .none, startRequest: Bool = true, completion: @escaping (CollectionManager) -> Void = {_ in }) { self.identifier = identifier self.completion = completion self.request = request self.startRequest = startRequest if self.request == .none { self.startRequest = false completion(self) return } if !self.startRequest { completion(self) return } ///Recreating a model is the same as all my properties (think about whether it can be optimized by implementing NSCopy later) ///startRequest is set to false to prevent repeated loop requests from falling into a dead loop let myNewItem = CollectionManager(self.identifier,request: self.request, startRequest: false, completion: self.completion) homeProvider.request(request) { (result) in var tmpItems: [ListDiffable] = [] //TODO: - data conversion switch request { case .gridItem: tmpItems = self.demoGridItems()// False data case .text: tmpItems = self.demoStrings() as [ListDiffable]// False data case .centerText: tmpItems = self.demoCenterStrings()// False data case .image: tmpItems = self.demoImageURLs() as [ListDiffable]// False data default: break } myNewItem.items = tmpItems if let listManager = ManagerCenter.shared[self.listManagerIdentifier], listManager.itemIdentifiers.contains(self.identifier) { //Re register and replace the original corresponding element listManager.register(myNewItem) self.completion(myNewItem) } } } }
- ManagerCenter: a single instance containing all listmanagers in the project.
- The project is decoupled and encapsulated again on the basis of IGListKit
- RowListSectionController
- HorizontalSectionController
- GridSectionController
- YILUtilKit: others.
- CollectionItem: the model in CollectionManager implements listdiffable (refer to IGListKit)
Request processing Moya
*Controlling multiple concurrent requests with semaphores in projects *Efficient loading of large image and network image spaceship *In the project, the random sleep (arc4random()%8) imitates the time-consuming of different threads, and the order of returning to refresh the display remains unchanged.
Thank you!
Thank you for XXX's long advice.