IOS buffer horizontal ScrollView

Often need to use horizontal sliding controls, controls there are also a Cell, like the horizontal UITableView. It is found that there are many horizontal UITableView schemes on the Internet, and even lateral sliding is achieved by rotating the UITableView.

IOS buffer horizontal ScrollView

I usually use UIScrollView to achieve horizontal sliding, but once loaded too much, Caton will appear. So I avoid Caton’s problems by adding the interface cache. It also implements protocol oriented programming by mimicking UITableView’s dataSource.

Implementation steps

Custom control HMHorizontalScrollView. First, lateral sliding is achieved by including the UIScrollView. Implementing content filling by adding HMHorizontalScrollCell. Set up a cache array of Cell to display the Cell in the multiplexed cache array.

The contents of the cache array need to be updated based on the location of the slider. The cache’s display changes according to the ScrollView’s slippage, ensuring that Cell has been waiting for display at that location before sliding to the next Cell.

Finally, protocol programming is realized by configuring DataSource to transfer the interface display configuration, and the display content is set by the return value of the protocol. First click event through Delegate.

IOS buffer horizontal ScrollView
class diagram

Cache principle

Defines an array that puts the display interface in an array. Each time you slide, recalculate the display position of the cache interface and change the location of the displayed interface.

If a screen can display 3 Cell, could be 4 Cell, this time you need to add a Cell before and after, to pre load the interface, when this will quickly slide more smoothly. By constantly updating the location and information of the displayed Cell, the caching mechanism can be completed.

IOS buffer horizontal ScrollView
schematic diagram

When left sliding, when No. 4 Cell slides out of the screen, move No. 5 Cell to the first position.
when sliding to the right, when No. 1 Cell slides out of the screen, move No. 0 Cell to the last position.
when you slide to the left or right, keep the data in the original order and change no more.

Extension HMHorizontalScrollView: UIScrollViewDelegate func scrollViewDidScroll (scrollView: _ {{/ / UIScrollView) first came in may slide down 64 scrollView.contentOffset.y = 0 if numberOfCacheView < maxNumberOfCacheView if scrollView.contentOffset.x < {return} {0; / / slide to the first resetItemViewOfStart (else) if scrollView.contentOffset.x + scrollView.w >}; scrollView.contentSize.width {/ / slide to the last one (resetItemViewOfEnd else if cells[1].frame.origin.x}) + cells[0].w + separatorWidth < scrollView.contentOffset.x (resetItemViewOfLeftPan) {/ / / / update the left slide last let (lastCellIndex = Int (cells.last?.frame.origin.x?? 0) / (cellSize.width + separatorWidth)) if lastCellIndex > 0 & & lastCellIndex < numberOfCells {_ = dataSource?.horizontalScrollView (in: self, cellAt: lastCellIndex else if cells[numberOfCacheView)}} - 2].frame.origin.x > scrollView.contentOffset.x + scrollView.frame.width (resetItemViewOfRightPan) {/ / slide / / update first let = Int (firstCellIndex (cells.first?.frame.origin.x?? 0) / (cellSize.width + separatorWidth)) if firstCellIndex > 0 & & firstCellIndex < numberOfCells {_ = dataSource?.horizontalScrollView (in: self, cellAt: firstCellIndex)}}} / / slide to the first Func (resetItemViewOfStart) {hm_for (cells) {cell, index in cell.x = separatorWidth + (cellSize.width + separatorWidth) * CGFloat (index) if let index = indexOf (x: cell.x) {_ = dataSource?.horizontalScrollView (in: self, cellAt: index)}}} / / slide to the last func (resetItemViewOfEnd) {{hm_for (cells) cell, index in cell.x = scrollView.contentSize.width (cellSize.width + separatorWidth) * CGFloat (numberOfCacheView - index) if let index = indexOf (x: cell.x) {_ = dataSource?.horizontalScrollView (in: self, cellAt: index)}}} / / func (resetItemViewOfLeftPan) slide left {let temp = cells.first! Temp.x =.X (cellSize.wi + cells.last! DTH + separatorWidth) hm_for (cells) {(cell, index) in if index < cells.count - 1 {cells[index] = cells[index + 1]} else {cells[index]}}} = temp / func (resetItemViewOfRightPan) right slide {let temp = cells.last temp.x = cells.first -.X!! (cellSize.width + separatorWidth hm_for (cells) {(cell), index in if index < cells.count) {cells[cells.count - 1 - index - 1] = cells[cells.count - index - 2] - index - cells[cells.count} else {1]}}} = temp func indexOf (x: CGFloat) -> Index? CellSize.width {if + separatorWidth! = 0 {return (x / Int (cellSize.width + separatorWidth))} return Nil}

Protocol oriented programming

Define a HMHorizontalScrollViewDataSource protocol, the protocol is mainly to obtain data source information. Set up a dataSource delegate to configure the data through the delegate at the implementation interface. When certain data is needed, the dataSource implements the protocol to retrieve the return value, which is the data needed.

  • Protocol HMHorizontalScrollViewDataSource: NSObjectProtocol cell numberOfCells {/ / number of func (in horizontalScrollView: HMHorizontalScrollView) -&gt Int; / / its width func viewWidth (in horizontalScrollView: HMHorizontalScrollView) -> CGFloat cell func horizontalScrollView (width / _ horizontalScrollView: HMHorizontalScrollView, cellSizeAt index: Index -&gt CGSize); / / return cell func horizontalScrollView (in horizontalScrollView: HMHorizontalScrollView, cellAt index: Index) -&gt HMHorizontalScrollCell;}
  • The number of fileprivate / / cell protocol using VAR numberOfCells: Int {return dataSource.NumberOfCells (in: self)??? 0} / / cell var cellSize: CGSize size fileprivate {return dataSource?.horizontalScrollView (self, cellSizeAt: 0)?? (CGSize) / fileprivate var viewWidth:} CGFloat {interface width return dataSource?.viewWidth (in: self)? 0}?


When the Cell of the display interface is small, caching is not needed and requires special processing.

When the ScrollView slides to the edge, you also need to recalculate the Cell layout, otherwise the hidden cache Cell will show up.

Marginal conditions need to be taken into account.

Through the dataSource configuration of HMHorizontialView data source, HMHorizontialView through multiplex display Cell, can load in more than one Cell at a time without caton.
UIScollView can perform horizontal sliding paging displays, but a single load of content will appear in Caton, avoiding Caton by reusing the displayed interface. The protocol oriented programming is implemented by imitating UITableView

Finally, someone recommended a job offer!

Demo address: