- 2月 11 週二 202022:41
[超好聽音樂] Alan Walker - Faded
- 1月 27 週一 202004:44
[超好聽音樂] Star Sky - Two Steps From Hell
- 1月 27 週一 202004:41
[超好聽音樂] Let Me Love You & Faded ( MASHUP cover by J.Fla )
- 11月 21 週四 201923:53
[Swift 5.1] `some` return type (Opaque Return Types)

1.可以return擁有associatedtype的"實際"型別
(假如有這些protocol及extension)
- 8月 26 週一 201909:24
[Swift] CollectionView scroll to header
extension UICollectionView {
public func scrollToSection(section: Int, animated: Bool) {
guard numberOfSections > section else {
return
}
guard numberOfItems(inSection: section) > 0 else {
return
}
let sectionY: CGFloat = { () -> CGFloat in
let indexPath = IndexPath(item: 0, section: section)
let top: CGFloat = 0
guard let attributes = layoutAttributesForItem(at: indexPath) else {
return top
}
switch attributes.representedElementCategory {
case .cell, .decorationView:
return top
case .supplementaryView:
guard let attributes = layoutAttributesForSupplementaryElement(ofKind: UICollectionView.elementKindSectionHeader, at: indexPath) else {
return top
}
return attributes.frame.origin.y
@unknown default:
return top
}
}()
var offsetY: CGFloat = sectionY - contentInset.top
if #available(iOS 11.0, *) {
offsetY -= safeAreaInsets.top
}
let offset = CGPoint(x: 0, y: offsetY)
setContentOffset(offset, animated: animated)
}
}
避免不同Layout或是沒有header的時候,在iOS 10發生Crash
public func scrollToSection(section: Int, animated: Bool) {
guard numberOfSections > section else {
return
}
guard numberOfItems(inSection: section) > 0 else {
return
}
let sectionY: CGFloat = { () -> CGFloat in
let indexPath = IndexPath(item: 0, section: section)
let top: CGFloat = 0
guard let attributes = layoutAttributesForItem(at: indexPath) else {
return top
}
switch attributes.representedElementCategory {
case .cell, .decorationView:
return top
case .supplementaryView:
guard let attributes = layoutAttributesForSupplementaryElement(ofKind: UICollectionView.elementKindSectionHeader, at: indexPath) else {
return top
}
return attributes.frame.origin.y
@unknown default:
return top
}
}()
var offsetY: CGFloat = sectionY - contentInset.top
if #available(iOS 11.0, *) {
offsetY -= safeAreaInsets.top
}
let offset = CGPoint(x: 0, y: offsetY)
setContentOffset(offset, animated: animated)
}
}
避免不同Layout或是沒有header的時候,在iOS 10發生Crash
- 8月 15 週四 201904:14
[Swift] 不同預設實作
- 7月 16 週二 201918:02
[Swift] 忘記加rawValue 的....保護措拖
import UIKit
- 4月 11 週四 201917:43
[Swift] 會call很多次,但只要最後一次
只跑一次的Globa function:
/// Run once after delay if no be called
///
/// - Parameters:
/// - delay: delay time
/// - saveCurrent: should put it to 'property scope'
/// - getCurrent: should pass 'weak' self property
/// - once: do once closure
func runOnce(delay: TimeInterval,
saveCurrent: inout DispatchTime?,
getCurrent: @autoclosure @escaping () -> DispatchTime?,
once: @escaping () -> Void)
{
let begin: DispatchTime = DispatchTime.now()
saveCurrent = begin
DispatchQueue.main.asyncAfter(deadline: begin + delay) {
guard let current = getCurrent(), current == begin else {
print("Ignore because still be called")
return
}
print("Run once")
once()
}
}
/// Run once after delay if no be called
///
/// - Parameters:
/// - delay: delay time
/// - saveCurrent: should put it to 'property scope'
/// - getCurrent: should pass 'weak' self property
/// - once: do once closure
func runOnce(delay: TimeInterval,
saveCurrent: inout DispatchTime?,
getCurrent: @autoclosure @escaping () -> DispatchTime?,
once: @escaping () -> Void)
{
let begin: DispatchTime = DispatchTime.now()
saveCurrent = begin
DispatchQueue.main.asyncAfter(deadline: begin + delay) {
guard let current = getCurrent(), current == begin else {
print("Ignore because still be called")
return
}
print("Run once")
once()
}
}
- 3月 25 週一 201910:14
[Swift] 泛型抽象工廠
protocol OrderPickUpViewModelFactoryProtocol {
}
extension OrderPickUpViewModelFactoryProtocol {
fileprivate typealias TResult = OrderPickUpCellViewModelUpProtocol
fileprivate func createRows(info: OrderDetailModel.ShuttleInfo, _: TDesc.Type, _: TLocation.Type, _: TSubDetail.Type, _: TTitle.Type) -> [TResult]
where TDesc: OrderPickUpDetailDescCellViewModelProtocol,
TLocation: OrderPickUpDetaiLocationCellViewModelProtocol,
TSubDetail: OrderPickUpDetailSubDetailCellViewModelProtocol,
TTitle: OrderPickUpDetailTitleCellViewModelProtocol
{
var rows: [TResult?] = []
rows.append(TTitle(titleText: "AAA")))
rows.append(TLocation(titleText: "BBB"))
// .....
return rows.dropNil
}
}
}
extension OrderPickUpViewModelFactoryProtocol {
fileprivate typealias TResult = OrderPickUpCellViewModelUpProtocol
fileprivate func createRows(info: OrderDetailModel.ShuttleInfo, _: TDesc.Type, _: TLocation.Type, _: TSubDetail.Type, _: TTitle.Type) -> [TResult]
where TDesc: OrderPickUpDetailDescCellViewModelProtocol,
TLocation: OrderPickUpDetaiLocationCellViewModelProtocol,
TSubDetail: OrderPickUpDetailSubDetailCellViewModelProtocol,
TTitle: OrderPickUpDetailTitleCellViewModelProtocol
{
var rows: [TResult?] = []
rows.append(TTitle(titleText: "AAA")))
rows.append(TLocation(titleText: "BBB"))
// .....
return rows.dropNil
}
}
- 3月 08 週五 201917:58
[Swift] TruncatingTail不見
Label 設定AttributedText後,需重新指定LineBreakMode
titleLabel.attributedText = NSMutableAttributedString(string: viewModel.model.title, attributes: titleAttributes)
titleLabel.attributedText = NSMutableAttributedString(string: viewModel.model.title, attributes: titleAttributes)