Build Instagram App: Part 10 (Swift 5) - 2020 - Xcode 11 - iOS Development
private func bind(in output: AnyPublisher<ProfileTabsCollectionReusableView.Output, Never>) {
tabOutputSubscription = output
.receive(on: DispatchQueue.main)
.sink(receiveValue: { [weak self] result in
switch result {
case .taggedButtonDidTap: break
case .gridButtonDidTap: break
}
})
}
private func bind() {
gridButton
.tapPublisher
.sink { [weak self] _ in
self?.gridButton.tintColor = .systemBlue
self?.taggedButton.tintColor = .lightGray
self?.output.send(.gridButtonDidTap)
}
.store(in: &cancellables)
taggedButton
.tapPublisher
.sink { [weak self] _ in
self?.gridButton.tintColor = .lightGray
self?.taggedButton.tintColor = .systemBlue
self?.output.send(.taggedButtonDidTap)
}
.store(in: &cancellables)
}
func transform() -> AnyPublisher<Output, Never> {
return output.eraseToAnyPublisher()
}
enum Output {
case gridButtonDidTap
case taggedButtonDidTap
}
guard let tabControllHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: ProfileTabsCollectionReusableView.identifier, for: indexPath) as? ProfileTabsCollectionReusableView else { return UICollectionReusableView() }
if tabOutputSubscription == nil {
let output = tabControllHeader.transform()
bind(in: output)
}
return tabControllHeader
import UIKit
import Combine
class ProfileTabsCollectionReusableView: UICollectionReusableView {
struct Constants {
static let padding: CGFloat = 8
}
enum Output {
case gridButtonDidTap
case taggedButtonDidTap
}
static let identifier = "ProfileTabsCollectionReusableView"
private let gridButton: UIButton = {
let button = UIButton()
button.clipsToBounds = true
button.tintColor = .systemBlue
button.setBackgroundImage(UIImage(systemName: "square.grid.2x2"), for: .normal)
return button
}()
private let taggedButton: UIButton = {
let button = UIButton()
button.clipsToBounds = true
button.tintColor = .lightGray
button.setBackgroundImage(UIImage(systemName: "tag"), for: .normal)
return button
}()
private var cancellables = Set<AnyCancellable>()
private let output: PassthroughSubject<Output, Never> = .init()
override init(frame: CGRect) {
super.init(frame: frame)
setUI()
bind()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
let size = height - (Constants.padding * 2)
let gridButtonX = ((width / 2) - size) / 2
taggedButton.frame = CGRect(x: gridButtonX, y: Constants.padding, width: size, height: size)
gridButton.frame = CGRect(x: gridButtonX + (width / 2), y: Constants.padding, width: size, height: size)
}
private func setUI() {
backgroundColor = .systemBackground
addSubview(gridButton)
addSubview(taggedButton)
}
func transform() -> AnyPublisher<Output, Never> {
return output.eraseToAnyPublisher()
}
private func bind() {
gridButton
.tapPublisher
.sink { [weak self] _ in
self?.gridButton.tintColor = .systemBlue
self?.taggedButton.tintColor = .lightGray
self?.output.send(.gridButtonDidTap)
}
.store(in: &cancellables)
taggedButton
.tapPublisher
.sink { [weak self] _ in
self?.gridButton.tintColor = .lightGray
self?.taggedButton.tintColor = .systemBlue
self?.output.send(.taggedButtonDidTap)
}
.store(in: &cancellables)
}
}
import UIKit
import Combine
class UserFollowTableViewCell: UITableViewCell {
enum Output {
case followButtonDidTap(model: String)
}
static let identifier = "UserFollowTableViewCell"
private var cancellables = Set<AnyCancellable>()
private let profileImageView: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFill
return imageView
}()
private let nameLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 1
label.font = .systemFont(ofSize: 17, weight: .semibold)
return label
}()
private let userNameLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 1
label.font = .systemFont(ofSize: 16, weight: .regular)
return label
}()
private let followButton: UIButton = {
let button = UIButton()
return button
}()
private let output: PassthroughSubject<Output, Never> = .init()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setUI()
bind()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func prepareForReuse() {
super.prepareForReuse()
nameLabel.text = nil
profileImageView.image = nil
userNameLabel.text = nil
followButton.setTitle(nil, for: .normal)
followButton.backgroundColor = nil
followButton.layer.borderWidth = 0
}
override func layoutSubviews() {
super.layoutSubviews()
}
private func setUI() {
contentView.addSubview(nameLabel)
contentView.addSubview(profileImageView)
contentView.addSubview(followButton)
contentView.addSubview(userNameLabel)
contentView.clipsToBounds = true
}
func configure(with model: String) {
}
private func bind() {
}
func transform() -> AnyPublisher<Output, Never> {
return output.eraseToAnyPublisher()
}
}