iOS swift跑马灯滚动可以点击
跑马灯,从右至左循环滚动显示信息,并且支持点击事件,使用swift4.0语法完成,更加简介,通用性强,布局部分全部使用snpkit
代码:
//
// HXQMarqueeView.swift
// hxquan-swift
//
// Created by Tiny on 2018/11/20.
// Copyright © 2018年 hxq. All rights reserved.
// 跑马灯
import UIKit
class MarqueeModel: Equatable{
var title: String? //内容
var img: String? //头像图片 url
var textColor: UIColor = .black //字体默认颜色
var font: UIFont = .systemFont(ofSize: 14) //字体大小
var imageHolder: UIImage = HXQDefaultUserImage //头像默认图片
static func == (lhs: MarqueeModel, rhs: MarqueeModel) -> Bool {
return lhs.title == rhs.title &&
lhs.img == rhs.img &&
lhs.textColor == rhs.textColor &&
lhs.font == rhs.font &&
lhs.imageHolder == rhs.imageHolder
}
}
class MarqueeItem: UIView {
private var textLb: UILabel! //文字label
private var imgView: UIImageView! //图片
/// 重写setModel并赋值
fileprivate var model: MarqueeModel?{
didSet{
if model != nil {
textLb.text = model?.title
textLb.textColor = model!.textColor
textLb.font = model!.font
imgView.sd_setImage(with: URL(string: model!.img ?? ""), placeholderImage: model!.imageHolder)
}
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
private func setupUI(){
let gesture = UITapGestureRecognizer(target: self, action: #selector(itemClick))
addGestureRecognizer(gesture)
textLb = UILabel()
textLb.font = UIFont.systemFont(ofSize: 14)
textLb.textColor = UIColor.black
addSubview(textLb)
imgView = UIImageView()
imgView.layer.masksToBounds = true
addSubview(imgView)
imgView.snp.makeConstraints { (make) in
make.left.equalTo(5)
make.top.equalTo(5)
make.bottom.equalTo(-5)
make.width.equalTo(imgView.snp.height)
}
textLb.snp.makeConstraints { (make) in
make.centerY.equalToSuperview()
make.left.equalTo(imgView.snp.right).offset(5)
make.right.equalTo(-5)
}
}
/// item被点击事件回调
fileprivate var itemDidTap:(() -> Void)?
@objc private func itemClick(){
//将事件传递出去
itemDidTap?()
}
override func layoutSubviews() {
super.layoutSubviews()
imgView.layer.cornerRadius = imgView.bounds.size.width*0.5
}
}
class HXQMarqueeView: UIView {
/// 初始化scrollView
private lazy var scrollView: UIScrollView = {
let scrollView = UIScrollView(frame: .zero)
scrollView.scrollsToTop = false
scrollView.showsVerticalScrollIndicator = false
scrollView.showsHorizontalScrollIndicator = false
return scrollView
}()
/// 初始化定时器
private lazy var timer: Timer = {[unowned self] in
let timer = Timer(timeInterval: 0.008, target: self, selector: #selector(startToMove), userInfo: nil, repeats: true)
RunLoop.current.add(timer, forMode: .common)
return timer
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
private func setupUI(){
layer.masksToBounds = true
addSubview(scrollView)
scrollView.snp.makeConstraints { (make) in
make.top.left.bottom.equalToSuperview()
make.width.equalToSuperview()
}
}
var marqueeHolder: String?
var marqueeFontSize: CGFloat = 14
var marqueeTextColor = UIColor.black
public var items = [MarqueeModel](){
didSet{
//判断2次数据是否相同
if oldValue == items {
return
}
//关闭定时器
if timer.isValid {
timer.fireDate = Date.distantFuture
}
//移除scrollView中所有控件
for v in scrollView.subviews{
v.removeFromSuperview()
}
//显示默认
if items.isEmpty{
//如果需要显示默认值的话
if marqueeHolder != nil{
let lb = UILabel()
lb.textAlignment = .center
lb.text = marqueeHolder
lb.font = UIFont.systemFont(ofSize: marqueeFontSize)
lb.textColor = marqueeTextColor
scrollView.addSubview(lb)
lb.snp.makeConstraints { (make) in
make.height.equalToSuperview()
make.left.equalTo(20)
}
//更新scrollView的ContentSize
scrollView.snp.makeConstraints { (make) in
make.right.equalTo(lb.snp.right)
}
layoutIfNeeded()
scrollView.x = 0;
}
}else{
let margin: CGFloat = 10
let gap: CGFloat = 20
var last: MarqueeItem?
for (i,model) in items.enumerated(){
let item = MarqueeItem()
item.model = model
item.itemDidTap = { [unowned self] in
self.selectionBlock?(model,i)
}
scrollView.addSubview(item)
item.snp.makeConstraints { (make) in
if last == nil{
make.left.equalTo(margin)
}else{
make.left.equalTo(last!.snp.right).offset(gap)
}
make.height.equalToSuperview()
}
last = item
}
//更新scrollView的ContentSize
scrollView.snp.makeConstraints { (make) in
make.right.equalTo(last!.snp.right).offset(margin)
}
layoutIfNeeded()
//拿到contentSize重新更新scrollView约束
scrollView.snp.remakeConstraints { (make) in
make.width.equalTo(scrollView.contentSize.width)
make.top.bottom.equalToSuperview()
make.right.equalTo(last!.snp.right).offset(margin)
make.left.equalTo(self.snp.right)
}
//开始启动定时器
timer.fireDate = Date(timeIntervalSinceNow: 0)
}
}
}
private var selectionBlock: ((MarqueeModel,Int) -> Void)?
public func queeSelection(_ callBack: ((MarqueeModel,Int) -> Void)?){
selectionBlock = callBack
}
@objc private func startToMove(){
scrollView.x = scrollView.x - 0.5 ;
if scrollView.x <= -scrollView.contentSize.width {
scrollView.x = self.bounds.size.width;
}
}
deinit {
if timer.isValid {
timer.invalidate()
}
}
}
使用方法:
//创建
let marquee = HXQMarqueeView()
view.addSubview(marquee)
//设置约束
marquee.snp.makeConstraints { (make) in
make.left.equalTo(20)
make.right.equalTo(-20)
make.top.equalTo(100)
make.height.equalTo(30)
}
//初始化数据源
var array = [MarqueeModel]()
for i in 0..<5 {
let item = MarqueeModel()
item.title = "我完事了,你们呢\(i)"
item.img = ""
item.textColor = UIColor.black
item.font = UIFont.systemFont(ofSize: 14)
array.append(item)
}
//赋值
marquee.items = array
//监听点击
marquee.queeSelection { (model, index) in
print("\(model.title ?? "") + \(index)")
}
iOS swift跑马灯滚动可以点击的更多相关文章
- Android TextView 字数过多,用跑马灯滚动形式实现
上代码: <TextView android:layout_width="120dp" android:layout_height="wrap_content&qu ...
- Android 纵向跑马灯滚动效果
像淘宝和京东都会有跑马灯的效果,今天给大家贡献下以前项目的一个demo,各位看官,且看效果图. 我们先定义一个Bean文件,这个实体类文件主要包含标题,内容描述,以及还有跳转的链接. LampBean ...
- iOS中跑马灯效果小结
时光过得好快,记忆中刚刚从春节返回没有多久,清明.五一已飞逝而过,眨眼已到盛夏季节.不过还好,济南这两年不算太热,刚开始升温几天,一场及时雨总能让温度保持适宜.为了纪念一下青春的尾巴,也为了能有个健康 ...
- csdn左侧个人栏目美化,css英文颜色大全,跑马灯效果,点击转到qq联系,点击转到发送邮件。
跑马灯效果: <a href="http://mmmmmm.me" target="_blank"><marquee><font ...
- iOS 封装跑马灯和轮播效果
代码地址如下:http://www.demodashi.com/demo/14075.html 功能概述和预览 功能描述:WSL_RollView 是基于UICollectionView实现的支持水平 ...
- iOS swift版本无限滚动轮播图
之前写过oc版本的无限滚动轮播图,现在来一个swift版本全部使用snapKit布局,数字还是pageConrrol样式可选 enum typeStyle: Int { case pageContro ...
- android 总结(样式)—跑马灯 button的点击效果 RadioGroup 实现滑动的效果 button 下面有阴影 卡片样式
<Button android:layout_width="wrap_content" android:layout_height="wrap_content&qu ...
- iOS - 跑马灯、弹幕
1.跑马灯 具体实现代码见 GitHub 源码 QExtension QMarqueeView.h #pragma mark - QMarqueeViewDelegate /// 跑马灯内容点击处理协 ...
- javascript小记五则:用JS写一个图片左右自由滚动的“跑马灯”效果
之前看了很多百度搜索出的东西,十个有九个是不能实用的,个个讲的都不详细,今天详细给大家讲解下关于这个图片“跑马灯”滚动效果,源码如下: <!DOCTYPE html PUBLIC "- ...
随机推荐
- Context Menus
转载:http://open.chrome.360.cn/extension_dev/contextMenus.html 内容 清单 范例 API 参考: Chrome.contextMenus 方法 ...
- Hadoop数据目录迁移
Hadoop数据目录迁移 @(Hadoop) 随着数据的不断导入和增大,原本集群部署的目录磁盘空间不足了,所以要把hadoop存储数据的位置迁移到另外一个巨大的磁盘上,另外的一个用意是将数据和程序分离 ...
- [Android Pro] Android的5个进程等级
1.foreground process 正处于activity resume状态 正处于bound服务交互的状态 正处于服务在前台运行的状态(StartForeGround( ...
- JQuery的get、post和ajax方法的使用
在JQuery中可以使用get,post和ajax方法给服务器端传递数据 get方法的使用(customForGet.js文件): function verify(){ //1.获取文本框的数据 // ...
- 记录一个在制作Swing程序的小怪事
在制作一个Swing程序时,出现了奇怪的事情,程序在Eclipse里执行正常,但打包后再执行那些动态执行的控件就消失不见了.截图如下: 在Eclipse里正常执行的画面: 打包执行后出现的画面: 可以 ...
- 【转】Android之Adapter用法总结
1.概念 Adapter是连接后端数据和前端显示的适配器接口,是数据和UI(View)之间一个重要的纽带.在常见的View(ListView,GridView)等地方都需要用到Adapter.如下图直 ...
- Solidworks如何自动打开和关闭特征识别FeatureWorks
如果直接对已有的零件识别特征,可能会报错 删除多余的特征,先只保留一个输入(注意没有必要连草图也删掉,草图不会影响识别特征,你识别完了之后草图再接着该拉伸拉伸,该切除切除),然后再次执行识别特征, ...
- UML类图介绍(转载)
UML类图详细介绍 类图主要描述程序对象以及他们之间的关系.一般来说,类.接口.抽象类这些程序对象的区别很容易,但是他们之间六种关系以前总是理解不够深刻,这次进行了一次复习,顺便写成博文以便加深理 ...
- 七个你无法忽视的Git使用技巧
与其他技术相比,Git应该拯救了更多开发人员的饭碗.只要你经常使用Git保存自己的工作,你就一直有机会可以将代码退回到之前的状态,因此就可以挽回那些你深夜里迷迷糊糊犯下的错误. 尽管这么说,Git的命 ...
- MyBatis SpringBoot2.0 数据库读写分离
1.自定义DataSource import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; /** * @ ...