рдЕрдирдВрдд UIScrollView

рдЫрд╡рд┐

рдХрдИ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ, рдЖрдк рд╕реНрдХреНрд░реЙрд▓рд┐рдВрдЧ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╕рд╛рдордЧреНрд░реА рдХреЗ рдЕрдВрдд рдореЗрдВ рд╡рд┐рдкрд░реАрдд рджрд┐рд╢рд╛ рдореЗрдВ рдХрднреА рдирд╣реАрдВ рд▓рдкреЗрдЯрддрд╛ рд╣реИред рдпрд╣ рддрдХрдиреАрдХ рдХрдИ рдкреНрд▓реЗрдЯрдлрд╛рд░реНрдореЛрдВ рдкрд░ рдХрдИ рд╡рд░реНрд╖реЛрдВ рддрдХ рдорд╛рдирдХ рд░рд╣реА рд╣реИред рджреВрд╕рд░реА рдУрд░, рдЗрд╕ рдкреНрд░рднрд╛рд╡ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рддреГрддреАрдп-рдкрдХреНрд╖ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИрдВред рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдХрд┐рд╕реА рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдЗрд╕ рддрдХрдиреАрдХ рдореЗрдВ рдмрд╣реБрдд рд╕рд░рд▓ рддрд░реНрдХ рд╣реИред

рдкреГрд╖реНрда рдХрд╛ рд╕рдорд░реНрдерди UIScrollView рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдкреГрд╖реНрда рджреНрд╡рд╛рд░рд╛ рдЕрдкрдиреЗ рд╕рд╛рдордЧреНрд░реА рдкреГрд╖реНрда рдХреЛ рджреЗрдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред UIScrollView рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдЦреАрдВрдЪрдиреЗ рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдкрд░ рд╕реНрдХреНрд░реЙрд▓рд╡реНрдпреВ рдСрдлрд╝рд╕реЗрдЯ рдХреЛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░рдХреЗ рдЗрд╕ рдЖрд╢рдп рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рддрд╛ рд╣реИред рдЬрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреГрд╖реНрдареЛрдВ рдХреЗ рдЕрдВрдд рдореЗрдВ (рджрд╛рдИрдВ рдУрд░) рд╕реНрдХреНрд░реЙрд▓ рдХрд░рддрд╛ рд╣реИ, рддреЛ рд╕реНрдХреНрд░реЙрд▓рд╡реНрдпреВ рдЕрдкрдиреА рд╕рд╛рдордЧреНрд░реА рдХреА рдЕрддрд┐рд░рд┐рдХреНрдд рд╕реАрдорд╛ рдХреЛ рд╕реБрдВрджрд░ рдПрдиреАрдореЗрд╢рди рдХреЗ рд╕рд╛рде рд╡рд┐рдкрд░реАрдд рджрд┐рд╢рд╛ рдореЗрдВ рд▓реЗ рдЬрд╛рдХрд░ рд╕реАрдорд┐рдд рдХрд░ рджреЗрддрд╛ рд╣реИред

рдЫрд╡рд┐

рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдЬрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдкрдиреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдкрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╕реНрдХреНрд░реЙрд▓ рдСрдлрд╝ рдХрдВрдЯреЗрдВрдЯ рдСрдлрд╝рд╕реЗрдЯ рдХреЛ рд╕реАрдорд┐рдд рди рдХрд░реЗрдВред рдЗрд╕рд▓рд┐рдП, рд╣рдореЗрдВ UIScrollView рдореЗрдВ рджреЛ рдФрд░ рдкреГрд╖реНрда рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЕрдВрддрд┐рдо рдкреГрд╖реНрда рд╢реВрдиреНрдп рдЗрдВрдбреЗрдХреНрд╕ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдкрд╣рд▓рд╛ рдкреЗрдЬ рдЗрдВрдбреЗрдХреНрд╕ (рдирдВрдмрд░рдСрдлрдЗрдореНрд╕ + 1) рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛ред рдлрд┐рд░, рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ "рдирдВрдмрд░рдСрдлрд┐рдЯреНрд╕" рдкреЗрдЬ рдХреЛ рджреЗрдЦрддрд╛ рд╣реИ, рддреЛ рд╕реНрдХреНрд░реЙрд▓ рдХрдВрдЯреЗрдВрдЯ x рдСрдлрд╝рд╕реЗрдЯ 0 рдкрд░ рд╕реЗрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдбреЗрдХреНрд╕ 0 рдХреЛ рджреЗрдЦрддрд╛ рд╣реИ, рддреЛ рд╕реНрдХреНрд░реЙрд▓рд╡реНрдпреВ рдПрдХреНрд╕ рдХрдВрдЯреЗрдВрдЯ рдСрдлрд╝рд╕реЗрдЯ "рдкреЗрдЬрд╕рд╛рдЗрдЬрд╝ * рдирдВрдмрд░рдСрдлрд┐рдореНрд╕" рдкрд░ рд╕реЗрдЯ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред

рдЫрд╡рд┐

рдкрд╣рд▓реА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ UIView рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдПрдХ рдирдпрд╛ рд╡рд░реНрдЧ рдмрдирд╛рдирд╛ рд╣реИред

рдЫрд╡рд┐

BannerView рдиреАрдЪреЗ рдХреЗ рд░реВрдк рдореЗрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП:

import UIKit class BannerView: UIView { override init(frame: CGRect) { super.init(frame: frame) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } 

рдпрд╣рд╛рдВ рдХреБрдЫ рднреА рдЕрд╕рд╛рдорд╛рдиреНрдп рдирд╣реАрдВ рд╣реИред рдЕрдм рд╣рдореЗрдВ BannerView рдХреЗ рд▓рд┐рдП рд╕реНрдХреНрд░реЙрд▓рд╡реНрдпреВ рдФрд░ рд╕реЗрдЯрдЕрдк рдХреЛрдб рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛:

 import UIKit class BannerView: UIView { private let scrollView:UIScrollView = { let sc = UIScrollView(frame: .zero) sc.translatesAutoresizingMaskIntoConstraints = false sc.isPagingEnabled = true return sc }() // BannerView DataSources (1) private var itemAtIndex:((_ bannerView:BannerView , _ index:Int)->(UIView))! private var numberOfItems:Int = 0 override init(frame: CGRect) { super.init(frame: frame) setUpUI() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setUpUI() { scrollView.frame = CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height) scrollView.delegate = self self.addSubview(scrollView) scrollView.showsHorizontalScrollIndicator = false } func reloadData(numberOfItems:Int , itemAtIndex:@escaping ((_ bannerView:BannerView , _ index:Int)->(UIView)) ) { self.itemAtIndex = itemAtIndex self.numberOfItems = numberOfItems reloadScrollView() } private func reloadScrollView() { guard self.numberOfItems > 0 else { return } if self.numberOfItems == 1 { let firstItem:UIView = self.itemAtIndex(self , 0) addViewToIndex(view: firstItem, index: 0) scrollView.isScrollEnabled = false return } let firstItem:UIView = self.itemAtIndex(self , 0) addViewToIndex(view: firstItem, index: numberOfItems+1) let lastItem:UIView = self.itemAtIndex(self , numberOfItems-1) addViewToIndex(view: lastItem, index: 0) for index in 0..<self.numberOfItems { let item:UIView = self.itemAtIndex(self , index) addViewToIndex(view: item, index: index+1) } scrollView.contentSize = CGSize(width: CGFloat(numberOfItems+2)*scrollView.frame.size.width, height: scrollView.frame.size.height) scrollView.contentOffset = CGPoint(x: self.scrollView.frame.size.width, y: self.scrollView.contentOffset.y) } private func addViewToIndex(view:UIView, index:Int) { view.translatesAutoresizingMaskIntoConstraints = false scrollView.addSubview(view) view.frame = CGRect(x: CGFloat(index)*scrollView.frame.size.width, y: 0, width: scrollView.frame.size.width, height: scrollView.frame.size.height) } } 

рдореИрдВрдиреЗ рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП рдСрдЯреЛ рд▓реЗрдЖрдЙрдЯ рдХреЗ рдмрдЬрд╛рдп рдлреНрд░реЗрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореИрдВрдиреЗ рдкреНрд░рддрд┐рдирд┐рдзрд┐рдпреЛрдВ рдХреЗ рдмрдЬрд╛рдп рдХреНрд▓реЛрдЬрд░ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ред рдпрд╣ ViewController рдореЗрдВ рдЧрдВрджрдЧреА рд╕реЗ рдмрдЪрдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИред рдХреНрд▓реЛрдЬрд░ рдХреЗ рд╕рд╛рде, рдЖрдк рдХреЗрд╡рд▓ рдмреИрдирд░ рд╡реНрдпреВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 // ViewController.swift bannerView = BannerView(frame: CGRect(x: 0, y: 64, width: self.view.frame.size.width, height: 200)) self.view.addSubview(bannerView) bannerView.reloadData(numberOfItems: 5) { (bannerView, index) -> (UIView) in let view = UIView() view.backgroundColor = UIColor.red return view } 

UIScrollView рдХреЛ рджрд░реНрд╢рд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ scrollViewDidScroll (_ рд╕реНрдХреНрд░реЙрд▓ рджреГрд╢реНрдп: UIScrollView) рдХреЗ рдмрдЬрд╛рдп рд╕реНрдХреНрд░реЙрд▓рд╡реНрдпреВрдбрд╛рдИрдВрдбрдХреЗрдВрдбреЗрд▓рд░реЗрдЯрд┐рдВрдЧ (_ рд╕реНрдХреНрд░реЙрд▓ рджреГрд╢реНрдп: UIScrollView) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛ред рдХреНрдпреЛрдВрдХрд┐ рд╣рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рд╕реНрдХреНрд░реЙрд▓ рджреГрд╢реНрдп рдЖрдВрджреЛрд▓рди рдХреЗ рд╕рд╛рде рд╕реНрд╡реИрдк рд╕реНрдерд┐рддрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

 func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { let currentPage:Int = Int(scrollView.contentOffset.x / scrollView.frame.size.width) if currentPage == 0 { self.scrollView.contentOffset = CGPoint(x: scrollView.frame.size.width * CGFloat(numberOfItems), y: scrollView.contentOffset.y) } else if currentPage == numberOfItems { self.scrollView.contentOffset = CGPoint(x: 0, y: scrollView.contentOffset.y) } } 

рдФрд░ рдЕрдВрдд рдореЗрдВ, рд╣рдорд╛рд░рд╛ рдХреЛрдб BannerView.swift рдХреЗ рд▓рд┐рдП рдЗрд╕ рддрд░рд╣ рд╣реЛрдЧрд╛:

 // BannerView.swift import UIKit class BannerView: UIView , UIScrollViewDelegate{ private let scrollView:UIScrollView = { let sc = UIScrollView(frame: .zero) sc.translatesAutoresizingMaskIntoConstraints = false sc.isPagingEnabled = true return sc }() private var itemAtIndex:((_ bannerView:BannerView , _ index:Int)->(UIView))! private var numberOfItems:Int = 0 override init(frame: CGRect) { super.init(frame: frame) setUpUI() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } func reloadData(configuration:BannerViewConfiguration? , numberOfItems:Int , itemAtIndex:@escaping ((_ bannerView:BannerView , _ index:Int)->(UIView)) ) { self.itemAtIndex = itemAtIndex self.numberOfItems = numberOfItems reloadScrollView() } private func reloadScrollView() { guard self.numberOfItems > 0 else { return } if self.numberOfItems == 1 { let firstItem:UIView = self.itemAtIndex(self , 0) addViewToIndex(view: firstItem, index: 0) scrollView.isScrollEnabled = false return } let firstItem:UIView = self.itemAtIndex(self , 0) addViewToIndex(view: firstItem, index: numberOfItems+1) let lastItem:UIView = self.itemAtIndex(self , numberOfItems-1) addViewToIndex(view: lastItem, index: 0) for index in 0..<self.numberOfItems { let item:UIView = self.itemAtIndex(self , index) addViewToIndex(view: item, index: index+1) } scrollView.contentSize = CGSize(width: CGFloat(numberOfItems+2)*scrollView.frame.size.width, height: scrollView.frame.size.height) scrollView.contentOffset = CGPoint(x: self.scrollView.frame.size.width, y: self.scrollView.contentOffset.y) } private func addViewToIndex(view:UIView, index:Int) { view.translatesAutoresizingMaskIntoConstraints = false scrollView.addSubview(view) view.frame = CGRect(x: CGFloat(index)*scrollView.frame.size.width, y: 0, width: scrollView.frame.size.width, height: scrollView.frame.size.height) } func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { let currentPage:Int = Int(scrollView.contentOffset.x / scrollView.frame.size.width) if currentPage == 0 { self.scrollView.contentOffset = CGPoint(x: scrollView.frame.size.width * CGFloat(numberOfItems), y: scrollView.contentOffset.y) } else if currentPage == numberOfItems { self.scrollView.contentOffset = CGPoint(x: 0, y: scrollView.contentOffset.y) } } private func setUpUI() { scrollView.frame = CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height) scrollView.delegate = self self.addSubview(scrollView) scrollView.showsHorizontalScrollIndicator = false } } 

рдЫрд╡рд┐

рдкрд░рд┐рдгрд╛рдо


рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдордиреЗ рдереЛрдбрд╝рд╛ рддрд░реНрдХ рдХреЗ рд╕рд╛рде рдкреБрди: рдкреНрд░рдпреЛрдЬреНрдп рд╕реНрдХреНрд░реЙрд▓рд╡реНрдпреВ рдШрдЯрдХ рдмрдирд╛рдпрд╛ред рд╡реИрд╕реЗ, рднрд╛рд░реА рдорд╛рддреНрд░рд╛ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде UICollectionView рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдореЗрдВ UIScrollView рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмреЗрд╣рддрд░ рдкреНрд░рджрд░реНрд╢рди рдФрд░ рдмреЗрд╣рддрд░ рдореЗрдореЛрд░реА рдкреНрд░рдмрдВрдзрди рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рд╡рд┐рдХрд▓реНрдкреЛрдВ рдпрд╛ рджреНрд╡рд┐рджрд┐рд╢ рд╕реНрдХреНрд░реЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ InfiniteScrollView рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдереЛрдбрд╝реЗ рд╕реБрдзрд╛рд░ рдХреЗ рд╕рд╛рде, рдпрд╣ рдЖрдкрдХреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкреБрди: рдкреНрд░рдпреЛрдЬреНрдп рдЙрдкрдХрд░рдг рд╣реЛрдЧрд╛ред

тЖТ GitHub рдкрд░ рдкреВрд░реНрдг рд╕реНрд░реЛрдд рдХреЛрдб рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ

Source: https://habr.com/ru/post/hi453782/


All Articles