iOS-Swift-MJRefresh 重寫控制元件
GTMRefresh
GTMRefresh
用Swift重寫的MJRefresh
Introduction
- 自定義方便, Demo裡面有國內主流App的下拉效果的模仿
- 程式碼簡潔,總程式碼量不超過1000行
- 支援國際化
- 支援: UITableView, UICollectionView, UIScrollView, UIWebView
Demo
直接下載程式碼,裡面Demo裡面有各種效果的自定義效果(因為時間比較緊,demo程式碼可能不夠漂亮)
Demo模仿的下拉效果
- YahooWeather
- Curve Mask
- Youku
- TaoBao
- QQ Video
- DianPing
Installation
Cocoapods
Install Cocoapods if need be.
$ gem install cocoapods
Add GTMRefresh
in your Podfile
.
use_frameworks!
pod 'GTMRefresh'
Then, run the following command.
$ pod install
Manual
Copy GTMRefresh
folder to your project. That’s it.
Note: Make sure that all files in GTMRefresh
版本
Vesrion 0.0.1
This version requires Xcode 8.0 and Swift 3.
使用幫助
Firstly, import GTMRefresh
.
import GTMRefresh
使用預設的下拉和上拉效果
self.tableView.gtm_addRefreshHeaderView {
[weak self] in
print("excute refreshBlock")
self .refresh()
}
self.tableView.gtm_addLoadMoreFooterView {
[weak self] in
print("excute loadMoreBlock")
self.loadMore()
}
程式碼觸發重新整理
self.tableView.triggerRefreshing()
自定義下拉重新整理效果
約定
- 必須繼承 GTMRefreshHeader
- 必須實現 SubGTMRefreshHeaderProtocol
SubGTMRefreshHeaderProtocol
public protocol SubGTMRefreshHeaderProtocol {
/// 狀態變成.idle
func toNormalState()
/// 狀態變成.refreshing
func toRefreshingState()
/// 狀態變成.pulling
func toPullingState()
/// 狀態變成.willRefresh
func toWillRefreshState()
/// 下拉高度/觸發高度 值改變
func changePullingPercent(percent: CGFloat)
/// 開始結束動畫前執行
func willBeginEndRefershing(isSuccess: Bool)
/// 結束動畫完成後執行
func willCompleteEndRefershing()
/// 控制元件的高度
///
/// - Returns: 控制元件的高度
func contentHeight() -> CGFloat
}
特殊效果的實現
- 當觸發重新整理的高度和控制元件高度不一樣時重寫willRefresHeight(),如Demo裡的:Curve Mask
/// 即將觸發重新整理的高度(特殊的控制元件需要重寫該方法,返回不同的數值)
///
/// - Returns: 觸發重新整理的高度
open func willRefresHeight() -> CGFloat {
return self.mj_h // 預設使用控制元件高度
}
- 當Loadding動畫顯示區域的高度和控制元件高度不一樣時重寫refreshingHoldHeight(),如Demo裡的:QQ
/// Loadding動畫顯示區域的高度(特殊的控制元件需要重寫該方法,返回不同的數值)
///
/// - Returns: Loadding動畫顯示區域的高度
open func refreshingHoldHeight() -> CGFloat {
return self.mj_h // 預設使用控制元件高度
}
Example
//
// TaoBaoRefreshHeader.swift
// PullToRefreshKit
//
// Created by luoyang on 10/12/16.
// Copyright © 2016年 luoyang. All rights reserved.
//
import UIKit
import GTMRefresh
class TaoBaoRefreshHeader: GTMRefreshHeader, SubGTMRefreshHeaderProtocol {
fileprivate let circleLayer = CAShapeLayer()
fileprivate let arrowLayer = CAShapeLayer()
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 230, height: 35))
fileprivate let textLabel = UILabel()
fileprivate let strokeColor = UIColor(red: 135.0/255.0, green: 136.0/255.0, blue: 137.0/255.0, alpha: 1.0)
override init(frame: CGRect) {
super.init(frame: frame)
setUpCircleLayer()
setUpArrowLayer()
textLabel.textAlignment = .center
textLabel.textColor = UIColor.lightGray
textLabel.font = UIFont.systemFont(ofSize: 14)
textLabel.text = "下拉即可重新整理..."
imageView.image = UIImage(named: "taobaoLogo")
self.contentView.addSubview(imageView)
self.contentView.addSubview(textLabel)
}
func setUpArrowLayer(){
let bezierPath = UIBezierPath()
bezierPath.move(to: CGPoint(x: 20, y: 15))
bezierPath.addLine(to: CGPoint(x: 20, y: 25))
bezierPath.addLine(to: CGPoint(x: 25,y: 20))
bezierPath.move(to: CGPoint(x: 20, y: 25))
bezierPath.addLine(to: CGPoint(x: 15, y: 20))
self.arrowLayer.path = bezierPath.cgPath
self.arrowLayer.strokeColor = UIColor.lightGray.cgColor
self.arrowLayer.fillColor = UIColor.clear.cgColor
self.arrowLayer.lineWidth = 1.0
self.arrowLayer.lineCap = kCALineCapRound
self.arrowLayer.bounds = CGRect(x: 0, y: 0,width: 40, height: 40)
self.arrowLayer.anchorPoint = CGPoint(x: 0.5, y: 0.5)
self.layer.addSublayer(self.arrowLayer)
}
func setUpCircleLayer(){
let bezierPath = UIBezierPath(arcCenter: CGPoint(x: 20, y: 20),
radius: 12.0,
startAngle:CGFloat(-M_PI/2),
endAngle: CGFloat(M_PI_2 * 3),
clockwise: true)
self.circleLayer.path = bezierPath.cgPath
self.circleLayer.strokeColor = UIColor.lightGray.cgColor
self.circleLayer.fillColor = UIColor.clear.cgColor
self.circleLayer.strokeStart = 0.05
self.circleLayer.strokeEnd = 0.05
self.circleLayer.lineWidth = 1.0
self.circleLayer.lineCap = kCALineCapRound
self.circleLayer.bounds = CGRect(x: 0, y: 0,width: 40, height: 40)
self.circleLayer.anchorPoint = CGPoint(x: 0.5, y: 0.5)
self.layer.addSublayer(self.circleLayer)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
textLabel.frame = CGRect(x: 0,y: 0,width: 120, height: 40)
//放置Views和Layer
imageView.center = CGPoint(x: frame.width/2, y: frame.height - 60 - 18)
textLabel.center = CGPoint(x: frame.width/2 + 20, y: frame.height - 30)
self.arrowLayer.position = CGPoint(x: frame.width/2 - 60, y: frame.height - 30)
self.circleLayer.position = CGPoint(x: frame.width/2 - 60, y: frame.height - 30)
}
func toNormalState() {}
func toRefreshingState() {
self.circleLayer.strokeEnd = 0.95
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
rotateAnimation.toValue = NSNumber(value: M_PI * 2.0 as Double)
rotateAnimation.duration = 0.6
rotateAnimation.isCumulative = true
rotateAnimation.repeatCount = 10000000
self.circleLayer.add(rotateAnimation, forKey: "rotate")
self.arrowLayer.isHidden = true
textLabel.text = "重新整理中..."
}
func toPullingState() {}
func toWillRefreshState() {}
func changePullingPercent(percent: CGFloat) {
let adjustPercent = max(min(1.0, percent),0.0)
if adjustPercent == 1.0{
textLabel.text = "釋放即可重新整理..."
}else{
textLabel.text = "下拉即可重新整理..."
}
self.circleLayer.strokeEnd = 0.05 + 0.9 * adjustPercent
}
func willBeginEndRefershing(isSuccess: Bool) {}
func willCompleteEndRefershing() {
transitionWithOutAnimation {
self.circleLayer.strokeEnd = 0.05
};
self.circleLayer.removeAllAnimations()
self.arrowLayer.isHidden = false
textLabel.text = "下拉即可重新整理"
}
func contentHeight()->CGFloat{
return 60
}
/// MARK: Private
func transitionWithOutAnimation(_ clousre:()->()){
CATransaction.begin()
CATransaction.setDisableActions(true)
clousre()
CATransaction.commit()
}
}
自定義控制元件的使用
self.tableView.gtm_addRefreshHeaderView(refreshHeader: CustomRefreshHeader()) {
[unowned self] in
print("excute refreshBlock")
self.refresh()
}
自定義上拉載入效果
約定
- 必須繼承 GTMLoadMoreFooter
- 必須實現 SubGTMLoadMoreFooterProtocol
SubGTMLoadMoreFooterProtocol
public protocol SubGTMLoadMoreFooterProtocol {
func toNormalState()
func toNoMoreDataState()
func toWillRefreshState()
func toRefreshingState()
/// 控制元件的高度(自定義控制元件通過該方法設定自定義高度)
///
/// - Returns: 控制元件的高度
func contentHeith() -> CGFloat
}
相關推薦
iOS-Swift-MJRefresh 重寫控制元件
GTMRefresh GTMRefresh 用Swift重寫的MJRefresh Introduction 自定義方便, Demo裡面有國內主流App的下拉效果的模仿 程式碼簡潔,總程式碼量不超過1000行 支援國際化 支援: UITab
ios-swift-為圖片控制元件(自定義控制元件)新增點選事件
@IBOutlet var img_guanggao: UIImageView! override func viewDidLoad() { super.viewDidLoad(
IOS版App的控制元件元素定位
前言 Android版App的控制元件元素可以通過Android studio自帶的工具uiautomatorviewer來協助定位! IOS版App的控制元件元素可以通過Appium來實現(未實現),或app-inspector來實現,在此記錄app-inspector的使用 安裝 一、安裝Node
iOS-自定義的控制元件UILabel、、、touches等系列事件不執行問題
本文首發地址 解決答案在最下面··· 1.場景描述場景描述 我繼承了UILabel搞了一個自定義的控制元件。 在搞上一些觸控事件 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)e
iOS UIView及其子控制元件的常用設定
為控制元件新增邊框 view.layer.borderWidth = 1; view.layer.borderColor = [[UIColor blackColor] CGColor]; b
android仿ios的時間滾動控制元件WheelView
<LinearLayout android:layout_width="200dp" android:orientation="horizontal" android:layout_gravity=
android仿ios實現分段選擇控制元件UISegmentedControl
在ios7中有一種扁平風格的控制元件叫做分段選擇控制元件UISegmentedControl,控制元件上橫放或豎放著幾個被簡單線條隔開的按鈕,每次點選能切換不同的按鈕和按鈕所對應的介面,比如qq客戶端V6.5.3版本中訊息頁與電話頁分離就是用的這種原理。但是很可
iOS開發——解決UIScrollView控制元件移動錯位和無法滾動
跟著iOS老師發的教程做了個簡陋的圖片瀏覽器,因為圖片太多展示不開所以想要用Scroll View來顯示,就自己試了一下。然而並沒有自己想象的那麼順利orz 當把要顯示的圖片都放置到Scroll View上時,它還是不會滾動。這時因為沒有設定他的content
Swift 畫線控制元件(支援xib和storyboard)
因專案中經常用到各種分割線,索性封裝了一個畫線的控制元件。 特性 支援在xib中使用 支援設定線的顏色 支援設定線的粗細 padding屬性 支援橫線和豎線 支援畫虛線 可設定虛線間隔 可
[ ios ] 摺疊顯示文字控制元件
使用第三方控制元件"ZybTextView",可以方便的摺疊顯示大量文字。只需呼叫初始化方法,指定要顯示的文字的標題陣列和內容陣列。 使用方法,1.匯入標頭檔案,2.呼叫初始化方法。程式碼與效果如下
c# 如何重寫控制元件的OnPaint事件
使用OnPaint事件可以隨時繪製圖形 呼叫窗體的OnPaint事件 protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); //繪圖 } 但是如何重寫控制元件的OnPaint
動態改變listctrl 單元格背景及文字顏色(非重寫控制元件)
CListCtrl 類裡面沒有直接改變單元格背景及文字顏色的成員函式,只有改變整個背景的顏色。我有時候只是需要把某個單元格的顏色改變來突出顯示就可以了: 我們可以通過過載ListCtrl控制元件的Customdraw 訊息,然後在裡面寫一些程式碼就可以了; void
swift 自定義控制元件在StoryBoard(xib)裡使用的屬性
有時候我們在StoryBoard裡用拖拽方法建立屬性的時候,總會有一些常用的屬性沒有提供視覺化操作,所以我們必須在連線類中用程式碼去實現,雖然也比較簡單,但是這樣重複的操作大大的增加了開發時間,如果能在拖拽的介面就能直接除錯相關屬性,就像一個UIView直接視覺化設定背景顏
iOS銀聯ApplePay控制元件開發
自從今早上蘋果準備向大陸開發Apple Pay,朋友圈以及各種QQ群裡就開始炸開了鍋,而且據說有幾個比較前衛的公司已經開始支援了Apple Pay,所以呢,我們的產品老大也閒不住了,加上自己還是比較感興趣的,於是乎,自己開始東西寫Demo了,就當趕個潮流吧。
iOS系統自帶控制元件 UIBarButtonSystemItem 的樣式解析
UIBarButtonSystemItem的樣式解析 樣式 圖片 UIBarButtonSystemItemDone UIBarButtonSystemItemCancel UIBarButton
ios 通過設定UI控制元件的center和size來設定位置時需注意!
<iframe id="iframeu848856_0" src="http://pos.baidu.com/mccm?rdid=848856&dc=2&di=u848856&dri=0&dis=0&dai=2&
iOS 自定義重新整理控制元件UIScrollView (Refresh)
前言: 開發的時候經常會用到下拉重新整理這個控制元件,一直以來想自己寫一個,但是時間問題,都是使用別人寫好的,今天查了資料,自己自定一個 1.主要原理: a.建立UIScrollView的類目 提供 類似addHeaderRefresh等方法,這樣tabl
iOS masonry動態約束控制元件位置
#import "FourViewController.h" #import "View+MASAdditions.h" #import "FiveViewControllerr.h" #define WS(weakSelf) __weak __typeof(&
Android仿iOS左右滑動開關控制元件(Android4.0以上適用)
上週使用Android的switch模仿iOS的左右滑動開關控制元件,程式碼如下: aty_switch.xml: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android
ios學習之UI控制元件的一些基本使用
第一次寫部落格,主要是想記錄一下自己的對ios開發的一些心得 先上一張個人做的QQ登入介面的圖 在這個介面裡,有2個text,2個label,1個button,其中所有的屬性都是在inspector這裡面修改的,如圖所示藍色圖示即為inspector 在輸入QQ號和