仿網易新聞頭部多按鈕選擇器-SegmentControl-Swift
之前寫過一個OC版的簡易SegmentControl,按鈕佈局是平分的,樣子是這個樣子的(下圖)
demo地址
今天這款 是Swift版本的,佈局使按照文字的長度,如果按鈕個數少的話,是平分的,並且不可以滑動。如果按鈕個數多,是平分的,可有滑動,並且會把點選到的按鈕儘量放置在中間。
demo地址
效果圖如下:
-
檔案目錄
- 使用方法
let segmentC = PSSSegmentControl.init(frame: CGRect.init(x: 0, y: 20, width: kScreenWidth, height: 40), titleArray: dataArr);
segmentC.normalColor = UIColor.lightGray
segmentC.selectedColor = UIColor.orange
segmentC.backgroundColor = UIColor.white
segmentC.pss_font = UIFont.systemFont(ofSize: 17)
segmentC.pss_margin = 20
segmentC.pss_duration = 0.2
segmentC.pss_scale = 1.2
segmentC.selectedIndex = 0 // 這個需要給定初始值
self.view.addSubview(segmentC)
self.segmentC = segmentC
weak var weakSelf = self
// segmentC點選事件
segmentC.clickBlock = {
(index: NSInteger) in
weakSelf?.scrollView.setContentOffset(CGPoint.init(x: CGFloat(index) * kScreenWidth, y: 0), animated: true)
}
- 程式碼實現
import UIKit
let PSS_TagBase: NSInteger = 200
typealias PSSClickBlock = (_ index: NSInteger)->Void
class PSSSegmentControl: UIView, PSSItemViewDelegate {
// MARK: 開放屬性
var selectedIndex: NSInteger = 0 {
willSet {
let item0 = self.itemArray[self.selectedIndex]
let item1 = self.itemArray[newValue]
item0.pss_selected = false
item1.pss_selected = true
if self.ingoreSet {
self.ingoreSet = false
return
}
self.scrollTo(index: newValue)
}
}
var normalColor = UIColor.darkGray {
didSet {
for item in self.itemArray {
item.pss_normalColor = normalColor
}
}
}
var selectedColor = UIColor.red {
didSet {
for item in self.itemArray {
item.pss_selectedColor = selectedColor
}
}
}
var pss_duration: CGFloat = 0.1 {
didSet {
for item in self.itemArray {
item.pss_duration = self.pss_duration
}
}
}
var pss_scale: CGFloat = 1.1 {
didSet {
for item in self.itemArray {
item.pss_scale = self.pss_scale
}
}
}
var pss_margin: CGFloat = 15 {
didSet {
self.layoutSubviews()
}
}
var pss_font: UIFont = UIFont.systemFont(ofSize: 15) {
didSet {
for item in self.itemArray {
item.pss_font = pss_font
}
self .layoutSubviews()
}
}
// 點選事件回撥
var clickBlock: PSSClickBlock!
// MARK: 只讀屬性
private(set) var titleArray: [String]!
private(set) var itemArray:[PSSItemView] = [PSSItemView]()
// MARK: 私有屬性
private var scrollView: UIScrollView!
private var ingoreSet: Bool = false
// MARK: 構造方法
init(frame: CGRect, titleArray: [String]) {
super.init(frame: frame)
self.titleArray = titleArray
for i in 0..<self.titleArray.count {
let text = self.titleArray[i]
let item = PSSItemView.init(frame: CGRect.init(x: 0, y: 0, width: 0, height: self.pss_height), title: text as NSString, font:self.pss_font)
item.tag = i + PSS_TagBase
self.itemArray.append(item)
item.pss_normalColor = self.normalColor
item.pss_selectedColor = self.selectedColor
item.pss_delegate = self
}
self.addSomeViews()
self.layoutGradientLayer()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: 開放方法
// MARK: 代理方法
func item(_ item: PSSItemView, didSelectAt index: NSInteger) {
self.scrollTo(index: index)
self.ingoreSet = true
self.selectedIndex = index
if let block = self.clickBlock {
block(index)
}
}
// MARK: 重寫方法
override func layoutSubviews() {
super.layoutSubviews()
self.scrollView.frame = self.bounds
let totalW = self.totalWidth()
self.scrollView.contentSize = CGSize.init(width: totalW > self.pss_width ? totalW : self.pss_width, height: self.pss_height)
self.scrollView.bounces = (totalW > self.pss_width)
var margin = (self.pss_width - totalW + self.pss_margin * CGFloat(self.itemArray.count + 1)) / CGFloat(self.itemArray.count + 1)
var x: CGFloat = totalW <= self.pss_width ? margin : self.pss_margin
self.scrollView.showsHorizontalScrollIndicator = false
margin = x
for i in 0..<self.itemArray.count {
let item = self.itemArray[i]
let wid = item.itemWidth
item.frame = CGRect.init(x: x, y: 0, width: wid, height: self.pss_height)
x += (wid + margin)
}
}
// MARK: 私有方法
private func addSomeViews() {
self.scrollView = UIScrollView.init(frame: CGRect.init(x: 0, y: 0, width: 0, height: 0))
self.addSubview(self.scrollView)
for item in self.itemArray {
self.scrollView.addSubview(item)
}
}
private func totalWidth() -> CGFloat {
var totalWid: CGFloat = self.pss_margin
for item in self.itemArray {
totalWid += (item.itemWidth + self.pss_margin)
}
return totalWid;
}
private func scrollTo(index: NSInteger) {
let itemV = self.itemArray[index]
let centerX = itemV.pss_centerX
if centerX <= self.pss_width / 2 {
self.scrollView.setContentOffset(CGPoint.init(x: 0, y: 0), animated: true)
} else if centerX >= self.scrollView.contentSize.width - self.pss_width / 2 {
self.scrollView.setContentOffset(CGPoint.init(x: self.scrollView.contentSize.width - self.pss_width, y: 0), animated: true)
} else {
let x = centerX - self.pss_width / 2
scrollView.setContentOffset(CGPoint.init(x: x, y: 0), animated: true)
}
}
private func layoutGradientLayer() {
let gradientLayer = CAGradientLayer.init()
gradientLayer.startPoint = CGPoint.init(x: 0, y: 0)
gradientLayer.endPoint = CGPoint.init(x: 1, y: 0)
gradientLayer.colors = [
UIColor.white.cgColor,
UIColor.white.withAlphaComponent(0).cgColor,
UIColor.white.withAlphaComponent(0).cgColor,
UIColor.white.cgColor
]
let margin = 0.02
let gradient = 0.05
let locations = [
margin,
margin + gradient,
1 - (margin + gradient),
1 - margin
]
gradientLayer.locations = locations as [NSNumber]?
gradientLayer.frame = self.bounds
self.layer.addSublayer(gradientLayer)
}
deinit {
print("PSSSegmentControll - 被銷燬了")
}
}
在這裡簡單的貼上了一下,如果想看實現,請下載demo
相關文章
- 【Flutter 專題】97 仿網易新聞標籤選擇器Flutter
- ReactNative 仿網易新聞UI DemoReactUI
- 仿網易新聞效果原始碼分析原始碼
- 單選多選按鈕
- 仿今日頭條按鈕loading效果
- 仿淘寶,京東多級地址選擇器
- 自繪按鈕實現顏色選擇器
- Java選擇框和單選按鈕Java
- 仿抖音點贊按鈕
- (android高仿系列)今日頭條 --新聞閱讀器 (轉載)Android
- radio 單選按鈕 選中多個
- HTML 單選按鈕實現 (性別選擇)(解讀)HTML
- 直播app原始碼,給elementUI的table表頭新增按鈕或者多選框APP原始碼UI
- 仿 360 市場下載按鈕
- 仿switch風格滑動按鈕
- 基於js實現點選按鈕回到頂部JS
- 懸浮按鈕點選回到頂部FloatingActionButton
- Android開發 如何使用選擇器(selector) 來實現點選按鈕變色Android
- 新聞稿釋出渠道分析 如何選擇新聞稿釋出公司
- 手機直播原始碼,點選按鈕,立即回到頂部原始碼
- 直播軟體搭建,點選按鈕自動回到頂部
- Android 自定義控制元件 按鈕滾動選擇Android控制元件
- 是否應該在未選中行時禁用刪除按鈕,還是應該在點選按鈕時提示選擇資料?
- 窗體(文字框,按鈕,單選按鈕,標籤)
- CSS多類選擇器CSS
- 每日CSS_仿蘋果平滑開關按鈕CSS蘋果
- CSS3選擇器02—CSS3部分選擇器CSSS3
- CSS實現帶箭頭按鈕CSS
- jQuery返回頂部按鈕詳解jQuery
- 自定義一個仿拼多多地址選擇器
- GAT新Bug:點選分頁按鈕頁面沒變
- 仿噹噹App首頁按鈕漸變動畫效果APP動畫
- 瀏覽器歷史,判斷是點選了後退按鈕還是前進按鈕瀏覽器
- MUI – IOS系統,相簿選擇照片後,點選確定按鈕無反應UIiOS
- 為什麼選擇新聞稿釋出推廣?
- JavaScript 點選按鈕返回底部JavaScript
- iOS仿滴滴預約用車時間選擇器iOS
- RecyclerView滑動到底部的時候點選按鈕直接返回頂部View