跑马灯,从右至左循环滚动显示信息,并且支持点击事件,使用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跑马灯滚动可以点击的更多相关文章

  1. Android TextView 字数过多,用跑马灯滚动形式实现

    上代码: <TextView android:layout_width="120dp" android:layout_height="wrap_content&qu ...

  2. Android 纵向跑马灯滚动效果

    像淘宝和京东都会有跑马灯的效果,今天给大家贡献下以前项目的一个demo,各位看官,且看效果图. 我们先定义一个Bean文件,这个实体类文件主要包含标题,内容描述,以及还有跳转的链接. LampBean ...

  3. iOS中跑马灯效果小结

    时光过得好快,记忆中刚刚从春节返回没有多久,清明.五一已飞逝而过,眨眼已到盛夏季节.不过还好,济南这两年不算太热,刚开始升温几天,一场及时雨总能让温度保持适宜.为了纪念一下青春的尾巴,也为了能有个健康 ...

  4. csdn左侧个人栏目美化,css英文颜色大全,跑马灯效果,点击转到qq联系,点击转到发送邮件。

    跑马灯效果: <a href="http://mmmmmm.me" target="_blank"><marquee><font ...

  5. iOS 封装跑马灯和轮播效果

    代码地址如下:http://www.demodashi.com/demo/14075.html 功能概述和预览 功能描述:WSL_RollView 是基于UICollectionView实现的支持水平 ...

  6. iOS swift版本无限滚动轮播图

    之前写过oc版本的无限滚动轮播图,现在来一个swift版本全部使用snapKit布局,数字还是pageConrrol样式可选 enum typeStyle: Int { case pageContro ...

  7. android 总结(样式)—跑马灯 button的点击效果 RadioGroup 实现滑动的效果 button 下面有阴影 卡片样式

    <Button android:layout_width="wrap_content" android:layout_height="wrap_content&qu ...

  8. iOS - 跑马灯、弹幕

    1.跑马灯 具体实现代码见 GitHub 源码 QExtension QMarqueeView.h #pragma mark - QMarqueeViewDelegate /// 跑马灯内容点击处理协 ...

  9. javascript小记五则:用JS写一个图片左右自由滚动的“跑马灯”效果

    之前看了很多百度搜索出的东西,十个有九个是不能实用的,个个讲的都不详细,今天详细给大家讲解下关于这个图片“跑马灯”滚动效果,源码如下: <!DOCTYPE html PUBLIC "- ...

随机推荐

  1. iOS:第三方框架MJPhotoBrowser图片浏览器的使用

    介绍:MJPhotoBrowser这个第三方库是MJ老师封装的一套用来浏览图片的浏览器,可是是本地图片.网络图片.gif图片等,其也依赖了SDWebImage.SVProgressHUD.YLGIFI ...

  2. SQL 之 Group By

    SQL 之 Group By Group By从字面意义上理解就是根据By指定的规则对数据进行分组,所谓的分组就是将一个数据表划分成若干个小区域. 例如:有这么一张表

  3. My97DatePicker日历控件配置

    一. 简介 1. 简介 目前的版本是:4.72 2. 注意事项 My97DatePicker目录是一个整体,不可破坏里面的目录结构,也不可对里面的文件改名,可以改目录名 My97DatePicker. ...

  4. svn: warning: xxxx is already under version control

    svn stat  查看当前目录下svn状态 svn remove xxxx svn add xxx svn ci -m "注释"

  5. 适合移动手机使用的js环形菜单特效插件

    blooming-menu是一款适合在移动手机上使用的js环形菜单插件.该环形菜单提供了众多的參数,通过结合CSS3动画制作出效果很炫酷的圆形菜单展开和隐藏动画效果. 以下是这个圆形菜单菜价的可用參数 ...

  6. vue - webpack.dev.conf.js for node-portfinder

    描述:获取当前可用的port. (vue-cli配置好了,一旦端口被占用,报错,再次运行时会打开:8080+1,依次类推...8080+n) 官网地址:https://www.npmjs.com/pa ...

  7. 算法笔记_061:蓝桥杯练习 字串统计(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 给定一个长度为n的字符串S,还有一个数字L,统计长度大于等于L的出现次数最多的子串(不同的出现可以相交),如果有多个,输出最长的,如果仍然 ...

  8. Java学习笔记3、变量、数据类型

    标识符 常见的命名规则(见名知意) 包名全部小写 类或者接口,一个单词:首字母大写,多个单词:每个单词首字母大写. 方法或者变量:一个单词:首字母小写,多个单词:从第二个单词开始,每个单词首字母大写. ...

  9. javascript 将内容复制到剪贴板

      javascript 将内容复制到剪贴板 CreateTime--2017年9月19日11:36:50 Author:Marydon js 操作剪贴板 1.设置剪贴板内容 UpdateTime-- ...

  10. angular开发中对请求数据层的封装

    代码地址如下:http://www.demodashi.com/demo/11481.html 一.本章节仅仅是对angular4项目开发中数据请求封装到model中 仅仅是在项目angular4项目 ...