Skip to content

Instantly share code, notes, and snippets.

@fumiyasac
Last active December 23, 2020 16:10
Show Gist options
  • Save fumiyasac/27f6d3577dc33a538afdc76a90495bc4 to your computer and use it in GitHub Desktop.
Save fumiyasac/27f6d3577dc33a538afdc76a90495bc4 to your computer and use it in GitHub Desktop.
UI実装であると嬉しいレシピブックVol.2掲載サンプル変更点
// UI実装であると嬉しいレシピブックVol.2掲載サンプル変更点
// 1. 掲載サンプル第2章に関する変更点のご紹介
// Alamofireを利用したAPI通信に関連する処理の変更点
// 主な変更箇所については、下記の2点となります。
// - UserAgentに付加する情報の組み立て
// - Promise型のデータを返却するための共通処理
class ArticleAPIManager {
// ・・・(省略)・・・
// MEMO: UserAgentに付加する情報の組み立て
private static let bundleIdentifier = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as! String
private static let requestHeader = HTTPHeaders(
arrayLiteral: HTTPHeader(name: "User-Agent", value: bundleIdentifier),
HTTPHeader(name: "Content-Type", value: "application/x-www-from-urlencoded")
)
// ・・・(省略)・・・
}
// MARK: - APIManagerProtocol
extension ArticleAPIManager: APIManagerProtocol {
// ・・・(省略)・・・
// MARK: - Private Function
// Promise型のデータを返却するための共通処理
private func handleArticlesApiRequest(url: String, params: [String : Any] = [:]) -> Promise<JSON> {
// MEMO: Alamofireでの通信処理をPromiseKitでラッピングする
// 注意: iOS13以降では、Alamofireを利用する際の「encoding」は下記の様に設定する。
// .getの場合はURLEncoding.default
// .post,.put,.deleteはJSONEncoding.default
// Alamofire5.x系からは変更がある点に注意
return Promise { seal in
AF.request(url, method: .get, parameters: params, encoding: URLEncoding.default, headers: ArticleAPIManager.requestHeader).validate().responseJSON { response in
switch response.result {
// 成功時の処理(以降はレスポンス結果を取得して返す)
case .success(let response):
let json = JSON(response)
seal.fulfill(json)
// 失敗時の処理(以降はエラーの結果を返す)
case .failure(let error):
seal.reject(error)
}
}
}
}
}
// AlamofireImageを利用した表示画像キャッシュ処理の変更点
// 以前はaf_setImageとしていた部分がaf.setImageの様な形となります。
final class MainArticleTableViewCell: UITableViewCell {
// ・・・(省略)・・・
@IBOutlet weak private var thumbnailImageView: UIImageView!
// ・・・(省略)・・・
// MARK: - Function
func setCell(_ mainArticle: MainArticleEntity) {
// 画像を表示する
if let thumbnailUrl = mainArticle.thumbnailUrl {
// 表示する画像に角丸をつけるためのフィルタ
let thumbnailFilter = AspectScaledToFillSizeWithRoundedCornersFilter(
size: thumbnailImageView.frame.size,
radius: 6.0
)
// 表示時のプレースホルダー画像・フィルタ・トランジションも引数に設定する
thumbnailImageView.af.setImage(
withURL: thumbnailUrl,
placeholderImage: UIImage(named: "placeholder"),
filter: thumbnailFilter,
imageTransition: .crossDissolve(0.2)
)
}
// ・・・(省略)・・・
}
// ・・・(省略)・・・
}
// 2. 掲載サンプル第3章に関する変更点のご紹介
// AnimatedCollectionViewLayoutでカードが回転するアニメーションを加える処理の変更点
// 以前に下記Issueの様な問題がありましたが、現在解決しているので当初の様に3D回転する形の表現へ変更しています。
// https://github.com/KelvinJin/AnimatedCollectionViewLayout/issues/54
final class GalleryViewController: UIViewController {
// ・・・(省略)・・・
@IBOutlet weak private var galleryCollectionView: UICollectionView!
// MARK: - Override
override func viewDidLoad() {
super.viewDidLoad()
setupGalleryCollectionView()
// ・・・(省略)・・・
}
// ・・・(省略)・・・
// MARK: - Private Function
private func setupGalleryCollectionView() {
// UICollectionViewに関する初期設定
galleryCollectionView.isPagingEnabled = true
galleryCollectionView.isScrollEnabled = true
galleryCollectionView.showsHorizontalScrollIndicator = false
galleryCollectionView.showsVerticalScrollIndicator = false
// UICollectionViewDelegate & UICollectionViewDataSourceに関する初期設定
galleryCollectionView.delegate = self
galleryCollectionView.dataSource = self
galleryCollectionView.registerCustomCell(GalleryCollectionViewCell.self)
// UICollectionViewに付与するアニメーションに関する設定
// MEMO: AnimatedCollectionViewLayoutでカードがInstagramの様に回転するアニメーションを加える
let layout = AnimatedCollectionViewLayout()
layout.animator = CubeAttributesAnimator()
layout.scrollDirection = .horizontal
galleryCollectionView.collectionViewLayout = layout
}
// ・・・(省略)・・・
}
// FloatingPanelを利用したセミモーダル表示に関連する処理の変更点
// FloatingPanelのレイアウト設定に関するクラスを下記の様な形の記載に変更しています。(従来よりも直感的な感じになりました!)
final class CommentFloatingPanelLayout: FloatingPanelLayout {
// MARK: - Computed Property
// 制約の基準値に関する設定
var position: FloatingPanelPosition {
return .bottom
}
// 初期化時のハーフモーダル位置の表示状態
var initialState: FloatingPanelState {
return .tip
}
// 全画面時・半分時・一番下部時の位置を決定する
// MEMO: 基準をSuperViewとする場合は「referenceGuide: .superview」とする
var anchors: [FloatingPanelState : FloatingPanelLayoutAnchoring] {
return [
.full:
// MEMO: 上部SafeAreaからの位置
FloatingPanelLayoutAnchor(
absoluteInset: 0.0,
edge: .top,
referenceGuide: .safeArea
),
.half:
// MEMO: 下部SafeAreaからの位置
FloatingPanelLayoutAnchor(
absoluteInset: 246.0,
edge: .bottom,
referenceGuide: .safeArea
),
.tip:
// MEMO: 下部SafeAreaからの位置
FloatingPanelLayoutAnchor(
absoluteInset: 64.0,
edge: .bottom,
referenceGuide: .safeArea
)
]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment