V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  V2SuperUser  ›  全部回复第 1 页 / 共 4 页
回复总数  76
1  2  3  4  
24 天前
回复了 lstz 创建的主题 问与答 如果能回到过去,你最想回到哪一年?
@BearPear 活着的人确很痛苦,只要闲下来,或者一闭眼就是她的音容笑貌
24 天前
回复了 lstz 创建的主题 问与答 如果能回到过去,你最想回到哪一年?
回到上个月 13 号,那天她选择结束了自己年轻的生命,可是真的时光能倒流吗
212 天前
回复了 gtalk 创建的主题 职场话题 来晒晒你的中秋节福利
锤子、鸡毛
@V2SuperUser 修正:两处 scrollTo(index: page%3 + cellCount+1)改为 scrollTo(index: page%3 + cellCount/2+1)
@V2SuperUser 为啥我的代码不能像 OP 一样有格式
根据 https://juejin.cn/post/6940140043042291748 的缩放效果改了一个,你试试效果

```Swift

import UIKit

class ViewController: UIViewController {

private let margin: CGFloat = 20
private var itemW: CGFloat = .zero
private let cellID = "baseCellID"
private let cellCount = 100
private var collectionView: UICollectionView!

override func viewDidLoad() {
super.viewDidLoad()
setUpView()
}

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
}

func setUpView() {
let layout = ZGFlowLayout()
let collH: CGFloat = 200
let itemH = collH - margin * 2
itemW = view.bounds.width - margin * 2 - 100
layout.itemSize = CGSize(width: itemW, height: itemH)
layout.minimumLineSpacing = margin
layout.scrollDirection = .horizontal

collectionView = UICollectionView(frame: CGRect(x: 0, y: 180, width: view.bounds.width, height: collH), collectionViewLayout: layout)
collectionView.backgroundColor = .black
collectionView.showsHorizontalScrollIndicator = false
collectionView.dataSource = self
collectionView.delegate = self

collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cellID)
view.addSubview(collectionView)
scrollTo(index: cellCount/2)
}
}

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource{

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return cellCount
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath)
let colors: [UIColor] = [.red, .yellow, .blue]
cell.backgroundColor = colors[indexPath.item % 3]
return cell
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let scrollStop = !scrollView.isTracking && !scrollView.isDragging && !scrollView.isDecelerating
guard scrollStop else { return }
ZGScrollViewDidEndScroll(scrollView: scrollView)
}

func scrollViewDidScroll(_ scrollView: UIScrollView) {
//防止滚动到最后或者最前,如果觉得改变时突兀,可以增加 cellCount
let page = getCurrentPage(scrollView: scrollView)
if page >= 95 || page <= 5 {
scrollTo(index: page%3 + cellCount+1)
}
}

private func ZGScrollViewDidEndScroll(scrollView: UIScrollView) {
let page = getCurrentPage(scrollView: scrollView)
scrollTo(index: page%3 + cellCount+1)
}

private func scrollTo(index: Int){
collectionView.scrollToItem(at: IndexPath(item: index, section: 0), at: .centeredHorizontally, animated: false)
}

private func getCurrentPage(scrollView: UIScrollView) -> Int{
//第一个 page 偏移量会少了多显示出来的一半,不使用之后的计算,直接判定为 0
var page: CGFloat = 0
if scrollView.contentOffset.x > 0 {
//计算单次滑动的偏移量
let scrollW = scrollView.frame.width
//显示的多出一半的宽度
let half = (scrollW - itemW)/2
//除第一个外其余每次滑动的偏移量
let eachOffset = (itemW+margin)
//第一个 cell 的偏移量
let firstOffset = eachOffset-half
page = (scrollView.contentOffset.x-firstOffset)/(eachOffset) + 1
}
return Int(page)
}
}

class ZGFlowLayout: UICollectionViewFlowLayout {

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let attributes = super.layoutAttributesForElements(in: rect)
let centerX = collectionView!.contentOffset.x + collectionView!.bounds.width / 2
attributes?.forEach({ (attr) in
let pad = abs(centerX - attr.center.x)
let factor = 0.0009
let scale = 1 / (1 + pad * CGFloat(factor))
attr.transform = CGAffineTransform(scaleX: scale, y: scale)
})
return attributes
}

override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
var targetPoint = proposedContentOffset
let centerX = proposedContentOffset.x + collectionView!.bounds.width / 2
let attrs = self.layoutAttributesForElements(in: CGRect(x: proposedContentOffset.x, y: proposedContentOffset.y, width: collectionView!.bounds.size.width, height: collectionView!.bounds.size.height))
var moveDistance: CGFloat = CGFloat(MAXFLOAT)
attrs!.forEach { (attr) in
if abs(attr.center.x - centerX) < abs(moveDistance) {
moveDistance = attr.center.x - centerX
}
}
if targetPoint.x > 0 && targetPoint.x < collectionViewContentSize.width - collectionView!.bounds.width {
targetPoint.x += moveDistance
}
return targetPoint
}

override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return true
}

override var collectionViewContentSize: CGSize {
return CGSize(width: sectionInset.left + sectionInset.right + (CGFloat(collectionView!.numberOfItems(inSection: 0)) * (itemSize.width + minimumLineSpacing)) - minimumLineSpacing, height: 0)
}
}


```
225 天前
回复了 serafin 创建的主题 Apple Lightning 苹果真的做到了“ 10 年不变”
@chengxiao
@chairuosen

别的我不知道,用 iPhone 十年尾插没坏过,用 typeC 的 iPad Pro 尾插一年前已经换过一次,现在又感觉出问题了,公司的 C to C 插 Mac 充不了电,用对象的 Apple 20w 充电头充不了电,插我家主机上的 C 口可以充电,USBA -C 能充电,就很烦
@LaGeNanRen 我给租赁公司说的一切问题请跟我的保险公司商量,保险公司说只赔修车钱,我主要担心的是时间过去一个多星期了还在清算中,如果到时候真要我出停运费,这个时间是不是越长对我越不利
@cmdOptionKana 是的,他应该是不经常开,我报了保险,勘察都讲清楚了他还是担心不肯让我走,其实就是个很小的事故
以我自己修车经验来看,那个喷漆 300 可以搞定,走保险会高点,也不会超过 2000 ,所以我给保险公司说如果对方修车不超过 2000 直接交强险,我的车就不用修,超过 2000 我就修我自己的车走商业险,我车子就中网和前杠裂开一点点,修不修都无所谓那种
1  2  3  4  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5024 人在线   最高记录 6543   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 27ms · UTC 09:38 · PVG 17:38 · LAX 02:38 · JFK 05:38
Developed with CodeLauncher
♥ Do have faith in what you're doing.