Skip to content

Commit

Permalink
Feature: FavoriteAdCell (#487)
Browse files Browse the repository at this point in the history
* Make RibbonView style changeable and rearrange class

* Add cell and viewModel

* Add demo

* Add snapshot test reference image

* Remove some demo code

* Use CGFloat constants for spacing, set separatorInset

* Add more button

* Add delegate and call it when tapping more button

* Update snapshot reference image

* Add helper method for creating labels

* Set default style for RibbonView and add override for init(frame:)
  • Loading branch information
bstien authored Jul 30, 2019
1 parent 0261144 commit 3d87a61
Show file tree
Hide file tree
Showing 8 changed files with 452 additions and 12 deletions.
185 changes: 185 additions & 0 deletions Demo/Cells/FavoriteAdTableViewCell/FavoriteAdCellDemoView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
//
// Copyright © FINN.no AS, Inc. All rights reserved.
//

import FinniversKit

private struct ViewModel: FavoriteAdTableViewCellViewModel {
let addressText: String?
let titleText: String?
let descriptionPrimaryText: String?
let descriptionSecondaryText: String?
let imagePath: String?
let ribbonStyle: RibbonView.Style
let ribbonTitle: String
}

class FavoriteAdCellDemoView: UIView {
private let viewModels = ViewModelFactory.create()

private lazy var tableView: UITableView = {
let tableView = UITableView(withAutoLayout: true)
tableView.delegate = self
tableView.dataSource = self
tableView.register(FavoriteAdTableViewCell.self)
tableView.separatorInset = .leadingInset(frame.width)
return tableView
}()

override init(frame: CGRect) {
super.init(frame: frame)
setup()
}

private func setup() {
addSubview(tableView)
tableView.fillInSuperview()
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

// MARK: - UITableViewDelegate

extension FavoriteAdCellDemoView: UITableViewDelegate {
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let isLastCell = indexPath.row == (viewModels.count - 1)

if isLastCell {
cell.separatorInset = .leadingInset(frame.width)
}

if let cell = cell as? FavoriteAdTableViewCell {
cell.loadImage()
}
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
}

// MARK: - UITableViewDataSource

extension FavoriteAdCellDemoView: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewModels.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeue(FavoriteAdTableViewCell.self, for: indexPath)
cell.configure(with: viewModels[indexPath.row])
cell.remoteImageViewDataSource = self

// Show a pretty color while we load the image
let colors: [UIColor] = [.toothPaste, .mint, .banana, .salmon]
cell.loadingColor = colors[indexPath.row % colors.count]

return cell
}
}

// MARK: - RemoteImageTableViewCellDataSource

extension FavoriteAdCellDemoView: RemoteImageViewDataSource {
func remoteImageView(_ view: RemoteImageView, cachedImageWithPath imagePath: String, imageWidth: CGFloat) -> UIImage? {
return nil
}

func remoteImageView(_ view: RemoteImageView, loadImageWithPath imagePath: String, imageWidth: CGFloat, completion: @escaping ((UIImage?) -> Void)) {
guard let url = URL(string: imagePath) else {
completion(nil)
return
}

// Demo code only.
let task = URLSession.shared.dataTask(with: url) { data, _, _ in
usleep(50_000)
DispatchQueue.main.async {
if let data = data, let image = UIImage(data: data) {
completion(image)
} else {
completion(nil)
}
}
}

task.resume()
}

func remoteImageView(_ view: RemoteImageView, cancelLoadingImageWithPath imagePath: String, imageWidth: CGFloat) {}
}

// MARK: - Private types

private struct ViewModelFactory {
static func create() -> [ViewModel] {
return [
ViewModel(
addressText: "Slottet",
titleText: "Påhengsmotor",
descriptionPrimaryText: "15 001,-",
descriptionSecondaryText: "Båtmotor til salgs・Utenbords・60 hk",
imagePath: "https://jwproperty.com/files/wp-content/uploads/2015/01/Smart_House-Valley_Hua_Hin0131.jpg",
ribbonStyle: .success,
ribbonTitle: "Aktiv"
),
ViewModel(
addressText: "Innkjøpsansvarlig, Acme Inc.",
titleText: "Kategoriansvarlig teknisk innkjøp",
descriptionPrimaryText: "Kategoriansvarlig teknisk innkjøp",
descriptionSecondaryText: "Fulltidsstilling・Acme Inc.・Søknadsfrist 2020-02-31・Fast",
imagePath: "http://i3.au.reastatic.net/home-ideas/raw/a96671bab306bcb39783bc703ac67f0278ffd7de0854d04b7449b2c3ae7f7659/facades.jpg",
ribbonStyle: .error,
ribbonTitle: "Slettet"
),
ViewModel(
addressText: "Asker",
titleText: "Godt brukt Sofa - pris kan diskuteres mot rask henting.",
descriptionPrimaryText: "2 000,-",
descriptionSecondaryText: "Torget",
imagePath: "http://jonvilma.com/images/house-6.jpg",
ribbonStyle: .warning,
ribbonTitle: "Solgt"
),
ViewModel(
addressText: "Røros",
titleText: "Worcestershire bøll terrier valper. Leveringsklare fra 21. August 2019",
descriptionPrimaryText: "17 000,-",
descriptionSecondaryText: "Torget",
imagePath: "https://i.pinimg.com/736x/11/f0/79/11f079c03af31321fd5029f72a4586b1--exterior-houses-house-exteriors.jpg",
ribbonStyle: .disabled,
ribbonTitle: "Frist utløpt"
),
ViewModel(
addressText: "Fredrikstad",
titleText: "Nesten ny bil / Panorama - Se utstyr! Innbytte mulig 2014, 69 700 km, kr 999 500,-",
descriptionPrimaryText: "2014 • 69 700 km • 999 500,-",
descriptionSecondaryText: "Bruktbil・Bil・Bensin",
imagePath: "https://i.pinimg.com/736x/bf/6d/73/bf6d73ab0234f3ba1a615b22d2dc7e74--home-exterior-design-contemporary-houses.jpg",
ribbonStyle: .success,
ribbonTitle: "Aktiv"
),
ViewModel(
addressText: "Sentrum, Navn Navnesens vei 42A, 0001 Oslo",
titleText: "BUD INNKOMMET! Lekker tomannsbolig med 70 soverom. Nydelige uteplasser! Garasje med innredet hems.",
descriptionPrimaryText: "128m² • 2 565 000,-",
descriptionSecondaryText: "Bolig til salgs・Eier (Selveier)・Tomannsbolig",
imagePath: "https://www.tumbleweedhouses.com/wp-content/uploads/tumbleweed-tiny-house-cypress-black-roof-hp.jpg",
ribbonStyle: .disabled,
ribbonTitle: "Deaktivert"
),
ViewModel(
addressText: "Østkanten, Helsfyrsveien 10A, 1010 Oslo",
titleText: "Nordvendt og lekkert rekkehus med mulighet for 2 soverom nær flotte t-baner og skoler.",
descriptionPrimaryText: "123m² • 2 750 000,-",
descriptionSecondaryText: "Bolig til salgs・1 989,- pr mnd・Eier (Selveier)・Andre・1 soverom",
imagePath: "https://i.pinimg.com/736x/73/de/32/73de32f9e5a0db66ec7805bb7cb3f807--navy-blue-houses-blue-and-white-houses-exterior.jpg",
ribbonStyle: .warning,
ribbonTitle: "Solgt"
)
]
}
}
3 changes: 3 additions & 0 deletions Demo/Demo/Demo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ public enum Cells: String, CaseIterable {
case heartSubtitleCell
case iconTitleCell
case remoteImageCell
case favoriteAdCell

public static var items: [Cells] {
return allCases.sorted { $0.rawValue < $1.rawValue }
Expand All @@ -180,6 +181,8 @@ public enum Cells: String, CaseIterable {
return DemoViewController<IconTitleCellDemoView>(withDismissButton: true)
case .remoteImageCell:
return DemoViewController<RemoteImageCellDemoView>(withDismissButton: true)
case .favoriteAdCell:
return DemoViewController<FavoriteAdCellDemoView>(withDismissButton: true)
}
}
}
Expand Down
28 changes: 28 additions & 0 deletions FinniversKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,13 @@
89A7A645225352380053D33B /* NativeAdvertDelegates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89A7A643225352180053D33B /* NativeAdvertDelegates.swift */; };
89A7A648225352A30053D33B /* NativeContentAdvertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89A7A6462253524E0053D33B /* NativeContentAdvertView.swift */; };
89A7A64A22536E200053D33B /* NativeContentSettingsButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89A7A64922536E200053D33B /* NativeContentSettingsButton.swift */; };
9A37D015952CBD1FEF4F0E20 /* FavoriteAdTableViewCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A37DA1C8FBA8E3FF6355FB5 /* FavoriteAdTableViewCellViewModel.swift */; };
9A37D36854B78610AFEADD5C /* UITableViewCellExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A37DF20BB7306D8D1A25593 /* UITableViewCellExtensions.swift */; };
9A37D6FADD7DBD952AA395F7 /* FavoriteAdTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A37D30A5DD3B5A286743DA3 /* FavoriteAdTableViewCell.swift */; };
9A37D9EDC4E78EC664D528FE /* FeedbackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A37D9749A60B9BFD125F483 /* FeedbackView.swift */; };
9A37DACD70E4383536D5312B /* FeedbackDemoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A37D31AFA28AABED492E588 /* FeedbackDemoView.swift */; };
9A37DC6E6F0401357C564B93 /* RemoteImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A37D61B28BC0BA6CA6110A5 /* RemoteImageView.swift */; };
9A37DDB3353F56739B23D22B /* FavoriteAdCellDemoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A37DECC59A6DBC8F54A7614 /* FavoriteAdCellDemoView.swift */; };
9B23769122DC6CEF00FCA381 /* NSLayoutAnchorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B23769022DC6CEF00FCA381 /* NSLayoutAnchorExtensions.swift */; };
9B238F02225B95F600B0E0C2 /* InfoboxView+Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B238F01225B95F600B0E0C2 /* InfoboxView+Style.swift */; };
9BC33DE322D71986007CCD65 /* LoginEntryViewDemoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BC33DE222D71986007CCD65 /* LoginEntryViewDemoView.swift */; };
Expand Down Expand Up @@ -674,9 +677,12 @@
89A7A643225352180053D33B /* NativeAdvertDelegates.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeAdvertDelegates.swift; sourceTree = "<group>"; };
89A7A6462253524E0053D33B /* NativeContentAdvertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeContentAdvertView.swift; sourceTree = "<group>"; };
89A7A64922536E200053D33B /* NativeContentSettingsButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeContentSettingsButton.swift; sourceTree = "<group>"; };
9A37D30A5DD3B5A286743DA3 /* FavoriteAdTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FavoriteAdTableViewCell.swift; sourceTree = "<group>"; };
9A37D31AFA28AABED492E588 /* FeedbackDemoView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedbackDemoView.swift; sourceTree = "<group>"; };
9A37D61B28BC0BA6CA6110A5 /* RemoteImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemoteImageView.swift; sourceTree = "<group>"; };
9A37D9749A60B9BFD125F483 /* FeedbackView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedbackView.swift; sourceTree = "<group>"; };
9A37DA1C8FBA8E3FF6355FB5 /* FavoriteAdTableViewCellViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FavoriteAdTableViewCellViewModel.swift; sourceTree = "<group>"; };
9A37DECC59A6DBC8F54A7614 /* FavoriteAdCellDemoView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FavoriteAdCellDemoView.swift; sourceTree = "<group>"; };
9A37DF20BB7306D8D1A25593 /* UITableViewCellExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITableViewCellExtensions.swift; sourceTree = "<group>"; };
9B23769022DC6CEF00FCA381 /* NSLayoutAnchorExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSLayoutAnchorExtensions.swift; sourceTree = "<group>"; };
9B238F01225B95F600B0E0C2 /* InfoboxView+Style.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "InfoboxView+Style.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1550,6 +1556,7 @@
44A557B022E72187001667AE /* SelectableTableViewCell */,
44A557A322E720A3001667AE /* IconTitleTableViewCell */,
44A557AB22E7211E001667AE /* RemoteImageTableViewCell */,
9A37DACFD214880B29DEBFA9 /* FavoriteAdTableViewCell */,
);
path = Cells;
sourceTree = "<group>";
Expand Down Expand Up @@ -1598,6 +1605,7 @@
44AEFC1A22E722FC00D3C307 /* BasicTableViewCell */,
44AEFC1D22E722FC00D3C307 /* IconTitleTableViewCell */,
44AEFC1F22E722FC00D3C307 /* SelectableTableViewCell */,
9A37DFB4ED453062D0BED7A9 /* FavoriteAdTableViewCell */,
);
path = Cells;
sourceTree = "<group>";
Expand Down Expand Up @@ -1881,6 +1889,15 @@
path = Feedback;
sourceTree = "<group>";
};
9A37DACFD214880B29DEBFA9 /* FavoriteAdTableViewCell */ = {
isa = PBXGroup;
children = (
9A37D30A5DD3B5A286743DA3 /* FavoriteAdTableViewCell.swift */,
9A37DA1C8FBA8E3FF6355FB5 /* FavoriteAdTableViewCellViewModel.swift */,
);
path = FavoriteAdTableViewCell;
sourceTree = "<group>";
};
9A37DBD671995665FDBC64C4 /* Feedback */ = {
isa = PBXGroup;
children = (
Expand All @@ -1889,6 +1906,14 @@
path = Feedback;
sourceTree = "<group>";
};
9A37DFB4ED453062D0BED7A9 /* FavoriteAdTableViewCell */ = {
isa = PBXGroup;
children = (
9A37DECC59A6DBC8F54A7614 /* FavoriteAdCellDemoView.swift */,
);
path = FavoriteAdTableViewCell;
sourceTree = "<group>";
};
9BC33DE122D7192F007CCD65 /* LoginEntry */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -3408,6 +3433,7 @@
9A37DACD70E4383536D5312B /* FeedbackDemoView.swift in Sources */,
9F21365157F385AC63928150 /* FullscreenGalleryDemoViewController.swift in Sources */,
DAE738C722C4C85E001C69E3 /* CarouselViewDemo.swift in Sources */,
9A37DDB3353F56739B23D22B /* FavoriteAdCellDemoView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -3679,6 +3705,8 @@
F2B1A19422D503E700713FC2 /* ReceiptViewModel.swift in Sources */,
9A37DC6E6F0401357C564B93 /* RemoteImageView.swift in Sources */,
9A37D36854B78610AFEADD5C /* UITableViewCellExtensions.swift in Sources */,
9A37D6FADD7DBD952AA395F7 /* FavoriteAdTableViewCell.swift in Sources */,
9A37D015952CBD1FEF4F0E20 /* FavoriteAdTableViewCellViewModel.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 3d87a61

Please sign in to comment.