Last active
September 28, 2023 08:38
-
-
Save HaruhikoMotokawa/12726da17dd824b49bbb9fe2403a6cec to your computer and use it in GitHub Desktop.
サイドメニューをハーフモーダルで実装してみた🤔
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
/// 画面遷移に関する処理を担うクラス | |
final class Router { | |
static let shared = Router() | |
private init() {} | |
/// TutorialMenuへモーダル遷移 | |
internal func showTutorialMenu(from: UIViewController) { | |
let toVC = TutorialMenuViewController() | |
toVC.modalPresentationStyle = .overCurrentContext | |
toVC.modalTransitionStyle = .crossDissolve | |
from.present(toVC, animated: false) { | |
toVC.showModal() | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
/// A-買い物リスト、継承を禁止するためにfinalキーワードつける | |
final class ShoppingListViewController: UIViewController { | |
// MARK: - @IBOutlet | |
/// チュートリアルを表示するボタン | |
@IBOutlet private weak var helpButton: UIButton! { | |
didSet { | |
helpButton.addTarget(self, action: #selector(helpButtonTapped), for: .touchUpInside) | |
} | |
} | |
/// チュートリアル画面へ遷移 | |
@objc private func helpButtonTapped() { | |
Router.shared.showTutorialMenu(from: self) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
/// チュートリアルのメニュー画面に使用するカスタムセル | |
final class TutorialTableViewCell: UITableViewCell { | |
/// セル登録時に使用するプロパティ | |
static var className: String { String(describing: TutorialTableViewCell.self) } | |
/// チュートリアル詳細画面に渡すアセッツ名を保持するプロパティ | |
private var imageName: String = "" | |
/// 大元のスタックビュー | |
private lazy var mainStackView: UIStackView = { | |
let mainStackView = UIStackView() | |
mainStackView.axis = .horizontal | |
mainStackView.alignment = .fill | |
mainStackView.distribution = .equalSpacing | |
mainStackView.spacing = 8 | |
mainStackView.addArrangedSubview(subStackView) | |
mainStackView.addArrangedSubview(arrowIcon) | |
mainStackView.translatesAutoresizingMaskIntoConstraints = false | |
return mainStackView | |
}() | |
/// 左側のアイコンとタイトルを配置するスタックビュー | |
private lazy var subStackView: UIStackView = { | |
let stackView = UIStackView() | |
stackView.axis = .horizontal | |
stackView.alignment = .leading | |
stackView.distribution = .fill | |
stackView.spacing = 8 | |
stackView.addArrangedSubview(iconImage) | |
stackView.addArrangedSubview(titleLabel) | |
return stackView | |
}() | |
/// 各コンテンツ用のアイコン | |
private var iconImage: UIImageView! = { | |
let image = UIImageView() | |
image.image = UIImage(systemName: "list.clipboard") | |
image.contentMode = .scaleAspectFit | |
image.tintColor = .black | |
return image | |
}() | |
/// タイトル | |
private var titleLabel: UILabel = { | |
let label = UILabel() | |
label.text = "これはテストです" | |
label.numberOfLines = 0 | |
return label | |
}() | |
/// 右端の矢印アイコン | |
private let arrowIcon: UIImageView! = { | |
let image = UIImageView() | |
image.contentMode = .scaleAspectFit | |
image.image = UIImage(systemName: "chevron.forward.circle") | |
image.tintColor = .black | |
return image | |
}() | |
/// セルが初期化された際の表示を決める | |
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { | |
super.init(style: style, reuseIdentifier: reuseIdentifier) | |
setupViews() | |
} | |
/// セルの再利用時の表示を決める | |
required init?(coder aDecoder: NSCoder) { | |
super.init(coder: aDecoder) | |
setupViews() | |
} | |
/// 制約を決める | |
private func setupViews() { | |
addSubview(mainStackView) | |
NSLayoutConstraint.activate([ | |
mainStackView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 3), | |
mainStackView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -3), | |
mainStackView.topAnchor.constraint(equalTo: topAnchor, constant: 8), | |
mainStackView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8) | |
]) | |
} | |
/// 表示するデータを配置する | |
func setData(icon: String, title: String, imageName: String) { | |
// enumは同一文字列指定できないので、ここで帳尻合わせ | |
if icon == "person.fill1" || | |
icon == "person.fill2" || | |
icon == "person.fill3" { | |
iconImage.image = UIImage(systemName: "person.fill") | |
} else { | |
iconImage.image = UIImage(systemName: icon) | |
} | |
titleLabel.text = title | |
self.imageName = imageName | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment