美文网首页
(Swift) 左右滑动缩放视图(中间大两侧小)

(Swift) 左右滑动缩放视图(中间大两侧小)

作者: 布呐呐u | 来源:发表于2021-09-26 19:28 被阅读0次

一) 使用场景

  • 多用于照片展示,左右滑动呈现缩放效果(中间大两侧小);
  • 封装为UIView对象,使用灵活;
  • 效果如下;


    o75k5-c7rug.gif

二) 使用方法

  • 5行代码,即可呈现;
  • 犹如使用UICollectionView般丝滑;
let zoomV = CCZoomCardView()
view.addSubview(zoomV)
zoomV.delegate = self
zoomV.register(CCTestCell.self, forCellWithReuseIdentifier: classString())
zoomV.snp.remakeConstraints { (make) in
  make.center.equalToSuperview()
  make.size.equalTo(CGSize(width: kScreenWidth(), height: (kScreenHeight().d * 0.6).i))
}
  • 注册自定义cell
zoomV.register(CCTestCell.self, forCellWithReuseIdentifier: classString())
  • 遵循'CCZoomCardViewDelegate'协议,并实现协议方法
    // MARK: - CCZoomCardViewDelegate
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        20
    }
    
    // MARK: - CCZoomCardViewDelegate
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        collectionView.dequeueReusableCell(withReuseIdentifier: classString(), for: indexPath) as! CCTestCell
    }
    
    // MARK: - CCZoomCardViewDelegate
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print(indexPath)
    }

三) 源码分享

//
//  CCZoomCardView.swift
//  HelloSwift
//
//  Created by well on 2021/9/26.
//

import UIKit

protocol CCZoomCardViewDelegate: NSObjectProtocol {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
}

// 自定义flowLayout
class CCZoomCardCollectionViewFlowLayout: UICollectionViewFlowLayout {
    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { true }
    
    override func prepare() {
        super.prepare()
        let margin = ((collectionView!.frame.width) - itemSize.width) / 2
        collectionView!.contentInset = UIEdgeInsets(top: 0, left: margin, bottom: 0, right: margin)
    }
    
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        let superArray = super.layoutAttributesForElements(in: rect)
        let tempArray = NSArray(array: superArray!, copyItems: true) as! [UICollectionViewLayoutAttributes]
        let centerX = collectionView!.contentOffset.x + collectionView!.frame.size.width * 0.5
        for item  in tempArray.enumerated() {
            let distance = abs(item.element.center.x - centerX)
            let scale = 1 - distance / (collectionView?.frame.width)!
            item.element.transform = CGAffineTransform(scaleX: scale, y: scale)
        }
        return tempArray
    }
    
    override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
        var contentOffset = proposedContentOffset
        let rect = CGRect(x: contentOffset.x, y: 0, width: collectionView!.frame.size.width, height: collectionView!.frame.size.height)
        let arr = super.layoutAttributesForElements(in: rect)
        let centerX: CGFloat = contentOffset.x + collectionView!.frame.size.width * 0.5
        var minDistance = CGFloat(MAXFLOAT)
        for item  in arr!.enumerated() {
            let distance = item.element.center.x - centerX
            if (abs(distance) < abs(minDistance)) {
                minDistance = distance
            }
        }
        contentOffset.x += minDistance
        return contentOffset
    }
}

class CCZoomCardView: UIView, UICollectionViewDelegate, UICollectionViewDataSource {
    
    /// 代理对象
    weak var delegate: CCZoomCardViewDelegate?
    
    /// 懒加载flowLayout
    private lazy var flowLayout: CCZoomCardCollectionViewFlowLayout = {
        let layout = CCZoomCardCollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        layout.minimumLineSpacing = 0
        layout.minimumInteritemSpacing = 0
        return layout
    }()
    
    /// 懒加载collectionView
    private lazy var collectionView: UICollectionView = {
        let c = UICollectionView(frame: .zero, collectionViewLayout: flowLayout)
        c.delegate = self
        c.dataSource = self
        c.showsHorizontalScrollIndicator = false
        c.contentInsetAdjustmentBehavior = .never
        return c
    }()
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - 反初始化器
    deinit { print("CCZoomCardView deinit!") }
    
    // MARK: - 初始化器
    override init(frame: CGRect) {
        super.init(frame: .zero)
        self.setUI()
    }
    
    override func layoutSubviews() {
        flowLayout.itemSize = CGSize(width: self.frame.width * 0.6, height: self.frame.height * 0.6)
    }
    
    func setUI() {
        self.addSubview(collectionView)
        collectionView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
    }
    
    // MARK: - UICollectionViewDelegate
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        (delegate?.collectionView(collectionView, numberOfItemsInSection: section))!
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        (delegate?.collectionView(collectionView, cellForItemAt: indexPath))!
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        delegate?.collectionView(collectionView, didSelectItemAt: indexPath)
    }
    
    // MARK: - 注册自定义cell
    func register(_ cellClass: AnyClass?, forCellWithReuseIdentifier identifier: String) {
        collectionView.register(cellClass, forCellWithReuseIdentifier: identifier)
    }
}

四) 更多组件,传送门

GitHub

相关文章

  • (Swift) 左右滑动缩放视图(中间大两侧小)

    一) 使用场景 多用于照片展示,左右滑动呈现缩放效果(中间大两侧小); 封装为UIView对象,使用灵活; 效果如...

  • Viewpager的使用

    ViewPagerViewPager的功能就是可以使视图滑动,就像Lanucher左右滑动那样。 ViewPage...

  • swift排序视图 缩放展示视图

    SwiftPulldownMenu swift编写 动画式展示一个带有箭头的视图 需要自定义视图内部的内容...

  • 自定义ViewGroup(1)

    滑动左右两边的ListView独立滑动,滑动中间的ListView整体滑动 实现代码:

  • 左右两侧recyclerView相互滑动

    最近做项目需要用到两个RecyclerView互相联动的功能,类似美团外卖的点餐列表,不同的是项目用到的右侧是点击...

  • Android之ViewPager

    ViewPager的作用 ViewPager的功能就是可以使视图滑动,就像Lanucher左右滑动那样。ViewP...

  • h5有好用的图片缩放组件么

    大佬们,h5有好用的图片缩放组件么,支持手势缩放移动,左右滑动切换图片的 https://fengyuanchen...

  • IOS---视图缩放显示动画

    效果:视图从大--小缩放显示/小--大 (只是比例问题)方法1.直接show出view的时候:把下面的这段代码加到...

  • Android自定义Excel表格的效果

    整个视图分为3个部分,左边上下滑动的列表,右侧上部左右滑动的线性布局,右侧下部上下左右都能滑动的列表。 根容器拦截...

  • swift 滑动视图结构组件

    还是老规矩,先看效果图 当然我这些代码是在别人的基础上整理出来的,就这个滑动的时候文字大小和颜色的变化。 用法: ...

网友评论

      本文标题:(Swift) 左右滑动缩放视图(中间大两侧小)

      本文链接:https://www.haomeiwen.com/subject/zjqcnltx.html