forked from organicmaps/organicmaps
[iOS] fixed MAPSME-9555 app is crashing when open through review push.
This commit is contained in:
parent
84d0f50159
commit
88f010d3d5
10 changed files with 196 additions and 213 deletions
|
@ -1,184 +1,120 @@
|
|||
import UIKit
|
||||
|
||||
@IBDesignable final class ExpandableTextView: UIView {
|
||||
@IBInspectable var text: String = "" {
|
||||
didSet {
|
||||
guard oldValue != text else { return }
|
||||
update()
|
||||
}
|
||||
}
|
||||
|
||||
@IBInspectable var textColor: UIColor? {
|
||||
get { return settings.textColor }
|
||||
set {
|
||||
settings.textColor = newValue ?? settings.textColor
|
||||
update()
|
||||
}
|
||||
}
|
||||
|
||||
@IBInspectable var expandText: String {
|
||||
get { return settings.expandText }
|
||||
set {
|
||||
settings.expandText = newValue
|
||||
update()
|
||||
}
|
||||
}
|
||||
|
||||
@IBInspectable var expandTextColor: UIColor? {
|
||||
get { return settings.expandTextColor }
|
||||
set {
|
||||
settings.expandTextColor = newValue ?? settings.expandTextColor
|
||||
update()
|
||||
}
|
||||
}
|
||||
|
||||
@IBInspectable var numberOfCompactLines: Int {
|
||||
get { return settings.numberOfCompactLines }
|
||||
set {
|
||||
settings.numberOfCompactLines = newValue
|
||||
update()
|
||||
}
|
||||
}
|
||||
|
||||
var textFont: UIFont {
|
||||
get { return settings.textFont }
|
||||
set {
|
||||
settings.textFont = newValue
|
||||
update()
|
||||
}
|
||||
}
|
||||
|
||||
var settings = ExpandableTextViewSettings() {
|
||||
didSet { update() }
|
||||
}
|
||||
|
||||
var onUpdate: (() -> Void)?
|
||||
|
||||
override var frame: CGRect {
|
||||
didSet {
|
||||
guard frame.size != oldValue.size else { return }
|
||||
update()
|
||||
}
|
||||
}
|
||||
|
||||
override var bounds: CGRect {
|
||||
didSet {
|
||||
guard bounds.size != oldValue.size else { return }
|
||||
update()
|
||||
}
|
||||
}
|
||||
|
||||
private var isCompact = true {
|
||||
didSet {
|
||||
guard oldValue != isCompact else { return }
|
||||
update()
|
||||
}
|
||||
}
|
||||
|
||||
private func createTextLayer() {
|
||||
self.layer.sublayers?.forEach { $0.removeFromSuperlayer() }
|
||||
|
||||
var truncate = false
|
||||
let size: CGSize
|
||||
let fullSize = text.size(width: frame.width, font: textFont, maxNumberOfLines: 0)
|
||||
if isCompact {
|
||||
size = text.size(width: frame.width, font: textFont, maxNumberOfLines: numberOfCompactLines)
|
||||
truncate = size.height < fullSize.height
|
||||
if truncate {
|
||||
let expandSize = expandText.size(width: frame.width, font: textFont, maxNumberOfLines: 1)
|
||||
let layer = CATextLayer()
|
||||
layer.position = CGPoint(x: 0, y: size.height)
|
||||
layer.bounds = CGRect(origin: CGPoint(), size: expandSize)
|
||||
layer.anchorPoint = CGPoint()
|
||||
layer.string = expandText
|
||||
layer.font = CGFont(textFont.fontName as CFString)
|
||||
layer.fontSize = textFont.pointSize
|
||||
layer.foregroundColor = expandTextColor?.cgColor
|
||||
layer.contentsScale = UIScreen.main.scale
|
||||
|
||||
self.layer.addSublayer(layer)
|
||||
}
|
||||
} else {
|
||||
size = fullSize
|
||||
}
|
||||
|
||||
let layer = CATextLayer()
|
||||
layer.bounds = CGRect(origin: CGPoint(), size: size)
|
||||
layer.anchorPoint = CGPoint()
|
||||
layer.string = text
|
||||
layer.isWrapped = true
|
||||
layer.truncationMode = truncate ? kCATruncationEnd : kCATruncationNone
|
||||
layer.font = CGFont(textFont.fontName as CFString)
|
||||
layer.fontSize = textFont.pointSize
|
||||
layer.foregroundColor = textColor?.cgColor
|
||||
layer.contentsScale = UIScreen.main.scale
|
||||
|
||||
self.layer.addSublayer(layer)
|
||||
}
|
||||
|
||||
public override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
setup()
|
||||
}
|
||||
|
||||
public convenience init() {
|
||||
self.init(frame: CGRect())
|
||||
}
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
final class ExpandableReviewView: UIView {
|
||||
var contentLabel: UILabel = {
|
||||
let label = UILabel(frame: .zero)
|
||||
label.numberOfLines = 0
|
||||
label.clipsToBounds = true
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
return label
|
||||
}()
|
||||
|
||||
var moreLabel: UILabel = {
|
||||
let label = UILabel(frame: .zero)
|
||||
label.clipsToBounds = true
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
return label
|
||||
}()
|
||||
|
||||
var moreZeroHeight: NSLayoutConstraint!
|
||||
private var settings: ExpandableReviewSettings = ExpandableReviewSettings()
|
||||
private var isExpanded = false
|
||||
private var onUpdateHandler: (() -> Void)?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
setup()
|
||||
configureContent()
|
||||
}
|
||||
|
||||
public required init?(coder aDecoder: NSCoder) {
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
setup()
|
||||
configureContent()
|
||||
}
|
||||
|
||||
override func mwm_refreshUI() {
|
||||
super.mwm_refreshUI()
|
||||
textColor = textColor?.opposite()
|
||||
expandTextColor = expandTextColor?.opposite()
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
updateRepresentation()
|
||||
}
|
||||
|
||||
private func setup() {
|
||||
|
||||
func configureContent() {
|
||||
self.addSubview(contentLabel)
|
||||
self.addSubview(moreLabel)
|
||||
let labels: [String: Any] = ["contentLabel": contentLabel, "moreLabel": moreLabel]
|
||||
var contentConstraints: [NSLayoutConstraint] = []
|
||||
let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[contentLabel]-0-[moreLabel]",
|
||||
metrics: nil,
|
||||
views: labels)
|
||||
contentConstraints += verticalConstraints
|
||||
let moreBottomConstraint = bottomAnchor.constraint(equalTo: moreLabel.bottomAnchor)
|
||||
moreBottomConstraint.priority = .defaultLow
|
||||
contentConstraints.append(moreBottomConstraint)
|
||||
|
||||
let contentHorizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[contentLabel]-0-|",
|
||||
metrics: nil,
|
||||
views: labels)
|
||||
contentConstraints += contentHorizontalConstraints
|
||||
let moreHorizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[moreLabel]-0-|",
|
||||
metrics: nil,
|
||||
views: labels)
|
||||
contentConstraints += moreHorizontalConstraints
|
||||
NSLayoutConstraint.activate(contentConstraints)
|
||||
moreZeroHeight = moreLabel.heightAnchor.constraint(equalToConstant: 0.0)
|
||||
apply(settings: settings)
|
||||
|
||||
layer.backgroundColor = UIColor.clear.cgColor
|
||||
isOpaque = true
|
||||
gestureRecognizers = nil
|
||||
addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(onTap)))
|
||||
update()
|
||||
}
|
||||
|
||||
func apply(settings: ExpandableReviewSettings) {
|
||||
self.settings = settings
|
||||
self.contentLabel.textColor = settings.textColor
|
||||
self.contentLabel.font = settings.textFont
|
||||
self.moreLabel.font = settings.textFont
|
||||
self.moreLabel.textColor = settings.expandTextColor
|
||||
self.moreLabel.text = settings.expandText
|
||||
}
|
||||
|
||||
private var scheduledUpdate: DispatchWorkItem?
|
||||
|
||||
private func updateImpl() {
|
||||
createTextLayer()
|
||||
|
||||
invalidateIntrinsicContentSize()
|
||||
onUpdate?()
|
||||
override func mwm_refreshUI() {
|
||||
super.mwm_refreshUI()
|
||||
settings.textColor = settings.textColor.opposite()
|
||||
settings.expandTextColor = settings.expandTextColor.opposite()
|
||||
}
|
||||
|
||||
func update() {
|
||||
scheduledUpdate?.cancel()
|
||||
scheduledUpdate = DispatchWorkItem { [weak self] in self?.updateImpl() }
|
||||
DispatchQueue.main.async(execute: scheduledUpdate!)
|
||||
}
|
||||
|
||||
override var intrinsicContentSize: CGSize {
|
||||
var viewSize = CGSize()
|
||||
layer.sublayers?.forEach { layer in
|
||||
viewSize.width = max(viewSize.width, layer.frame.maxX)
|
||||
viewSize.height = max(viewSize.height, layer.frame.maxY)
|
||||
}
|
||||
return viewSize
|
||||
}
|
||||
|
||||
override func prepareForInterfaceBuilder() {
|
||||
super.prepareForInterfaceBuilder()
|
||||
updateImpl()
|
||||
|
||||
func configure(text: String, isExpanded: Bool, onUpdate: @escaping () -> Void) {
|
||||
contentLabel.text = text
|
||||
self.isExpanded = isExpanded
|
||||
contentLabel.numberOfLines = isExpanded ? 0 : settings.numberOfCompactLines
|
||||
onUpdateHandler = onUpdate
|
||||
}
|
||||
|
||||
@objc private func onTap() {
|
||||
isCompact = false
|
||||
if !isExpanded {
|
||||
isExpanded = true
|
||||
updateRepresentation()
|
||||
contentLabel.numberOfLines = 0
|
||||
onUpdateHandler?()
|
||||
}
|
||||
}
|
||||
|
||||
func updateRepresentation() {
|
||||
guard let text = contentLabel.text else {
|
||||
return
|
||||
}
|
||||
if isExpanded {
|
||||
moreZeroHeight.isActive = true
|
||||
} else {
|
||||
let height = (text as NSString).boundingRect(with: CGSize(width: contentLabel.bounds.width,
|
||||
height: .greatestFiniteMagnitude),
|
||||
options: .usesLineFragmentOrigin,
|
||||
attributes: [.font: contentLabel.font],
|
||||
context: nil).height
|
||||
if height > contentLabel.bounds.height {
|
||||
moreZeroHeight.isActive = false
|
||||
} else {
|
||||
moreZeroHeight.isActive = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
import UIKit
|
||||
|
||||
struct ExpandableTextViewSettings {
|
||||
enum Default {
|
||||
static let expandText = "…more"
|
||||
static let expandTextColor = UIColor.blue
|
||||
static let numberOfCompactLines = 2
|
||||
static let textColor = UIColor.darkText
|
||||
static let textFont = UIFont.preferredFont(forTextStyle: .body)
|
||||
struct ExpandableReviewSettings {
|
||||
var expandText: String
|
||||
var expandTextColor: UIColor
|
||||
var numberOfCompactLines: Int
|
||||
var textColor: UIColor
|
||||
var textFont: UIFont
|
||||
|
||||
init(expandText: String = "…more",
|
||||
expandTextColor: UIColor = .blue,
|
||||
numberOfCompactLines: Int = 2,
|
||||
textColor: UIColor = .darkText,
|
||||
textFont: UIFont = .preferredFont(forTextStyle: .body)) {
|
||||
self.expandText = expandText
|
||||
self.expandTextColor = expandTextColor
|
||||
self.numberOfCompactLines = numberOfCompactLines
|
||||
self.textColor = textColor
|
||||
self.textFont = textFont
|
||||
}
|
||||
|
||||
init() {}
|
||||
|
||||
var expandText = Default.expandText
|
||||
var expandTextColor = Default.expandTextColor
|
||||
var numberOfCompactLines = Default.numberOfCompactLines
|
||||
var textColor = Default.textColor
|
||||
var textFont = Default.textFont
|
||||
}
|
||||
|
|
|
@ -22,20 +22,22 @@ final class UGCReviewCell: MWMTableViewCell {
|
|||
}
|
||||
}
|
||||
|
||||
@IBOutlet private weak var reviewLabel: ExpandableTextView! {
|
||||
@IBOutlet private weak var reviewLabel: ExpandableReviewView! {
|
||||
didSet {
|
||||
reviewLabel.textFont = UIFont.regular14()
|
||||
reviewLabel.textColor = UIColor.blackPrimaryText()
|
||||
reviewLabel.expandText = L("placepage_more_button")
|
||||
reviewLabel.expandTextColor = UIColor.linkBlue()
|
||||
let settings = ExpandableReviewSettings(expandText: L("placepage_more_button"),
|
||||
expandTextColor: .linkBlue(),
|
||||
textColor: .blackPrimaryText(),
|
||||
textFont: .regular14())
|
||||
reviewLabel.apply(settings: settings)
|
||||
}
|
||||
}
|
||||
|
||||
@objc func config(review: UGCReview, onUpdate: @escaping () -> Void) {
|
||||
@objc func config(review: UGCReview, isExpanded: Bool, onUpdate: @escaping () -> Void) {
|
||||
titleLabel.text = review.title
|
||||
dateLabel.text = review.date
|
||||
reviewLabel.text = review.text
|
||||
reviewLabel.onUpdate = onUpdate
|
||||
reviewLabel.configure(text: review.text,
|
||||
isExpanded: isExpanded,
|
||||
onUpdate: onUpdate)
|
||||
ratingView.value = review.rating.value
|
||||
ratingView.type = review.rating.type
|
||||
isSeparatorHidden = true
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
@ -41,8 +41,8 @@
|
|||
<constraint firstAttribute="width" constant="48" placeholder="YES" id="TVO-Dx-h45"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="762-NT-BKz" customClass="ExpandableTextView" customModule="maps_me" customModuleProvider="target">
|
||||
<rect key="frame" x="16" y="78" width="288" height="40"/>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="762-NT-BKz" customClass="ExpandableReviewView" customModule="maps_me" customModuleProvider="target">
|
||||
<rect key="frame" x="16" y="77.5" width="288" height="40.5"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="d1v-ce-wSZ">
|
||||
|
|
|
@ -19,12 +19,13 @@ final class UGCYourReviewCell: MWMTableViewCell {
|
|||
}
|
||||
}
|
||||
|
||||
@IBOutlet private weak var reviewLabel: ExpandableTextView! {
|
||||
@IBOutlet private weak var reviewLabel: ExpandableReviewView! {
|
||||
didSet {
|
||||
reviewLabel.textFont = UIFont.regular14()
|
||||
reviewLabel.textColor = UIColor.blackPrimaryText()
|
||||
reviewLabel.expandText = L("placepage_more_button")
|
||||
reviewLabel.expandTextColor = UIColor.linkBlue()
|
||||
let settings = ExpandableReviewSettings(expandText: L("placepage_more_button"),
|
||||
expandTextColor: .linkBlue(),
|
||||
textColor: .blackPrimaryText(),
|
||||
textFont: .regular14())
|
||||
reviewLabel.apply(settings: settings)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,12 +46,13 @@ final class UGCYourReviewCell: MWMTableViewCell {
|
|||
}
|
||||
}
|
||||
|
||||
@objc func config(yourReview: UGCYourReview, onUpdate: @escaping () -> Void) {
|
||||
@objc func config(yourReview: UGCYourReview, isExpanded: Bool, onUpdate: @escaping () -> Void) {
|
||||
dateLabel.text = yourReview.date
|
||||
self.yourReview = yourReview
|
||||
reviewLabel.text = yourReview.text
|
||||
reviewLabel.configure(text: yourReview.text,
|
||||
isExpanded: isExpanded,
|
||||
onUpdate: onUpdate)
|
||||
reviewBottomOffset.constant = yourReview.text.isEmpty ? 0 : Config.defaultReviewBottomOffset
|
||||
reviewLabel.onUpdate = onUpdate
|
||||
updateCollectionView()
|
||||
isSeparatorHidden = true
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
@ -19,7 +19,7 @@
|
|||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="M3q-L0-4Y7" propertyAccessControl="all">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="135"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="134.5"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" verticalCompressionResistancePriority="751" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="nht-6C-S3i">
|
||||
<rect key="frame" x="16" y="16" width="42" height="20.5"/>
|
||||
|
@ -33,12 +33,12 @@
|
|||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="G4x-pj-fmv" customClass="ExpandableTextView" customModule="maps_me" customModuleProvider="target">
|
||||
<rect key="frame" x="16" y="78" width="288" height="40"/>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="G4x-pj-fmv" customClass="ExpandableReviewView" customModule="maps_me" customModuleProvider="target">
|
||||
<rect key="frame" x="16" y="77.5" width="288" height="40"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="aOE-yo-hUQ">
|
||||
<rect key="frame" x="16" y="134" width="304" height="1"/>
|
||||
<rect key="frame" x="16" y="133.5" width="304" height="1"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="1" id="E6L-PS-9ij"/>
|
||||
|
@ -64,7 +64,7 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" bounces="NO" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="none" prefetchingEnabled="NO" translatesAutoresizingMaskIntoConstraints="NO" id="w6j-GC-6Bv">
|
||||
<rect key="frame" x="0.0" y="135" width="320" height="55.5"/>
|
||||
<rect key="frame" x="0.0" y="134.5" width="320" height="56"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" priority="999" constant="56" id="2hn-mr-UAw"/>
|
||||
|
|
|
@ -555,8 +555,13 @@ map<MetainfoRows, Class> const kMetaInfoCells = {
|
|||
Class cls = [MWMUGCYourReviewCell class];
|
||||
auto c = static_cast<MWMUGCYourReviewCell *>(
|
||||
[tableView dequeueReusableCellWithCellClass:cls indexPath:indexPath]);
|
||||
[c configWithYourReview:static_cast<MWMUGCYourReview *>([ugc reviewWithIndex:indexPath.row])
|
||||
onUpdate:onUpdate];
|
||||
auto review = static_cast<MWMUGCYourReview *>([ugc reviewWithIndex:indexPath.row]);
|
||||
[c configWithYourReview:review
|
||||
isExpanded:[ugc isExpanded:review]
|
||||
onUpdate:^{
|
||||
[ugc markExpanded:review];
|
||||
onUpdate();
|
||||
}];
|
||||
return c;
|
||||
}
|
||||
case ReviewRow::Review:
|
||||
|
@ -564,8 +569,13 @@ map<MetainfoRows, Class> const kMetaInfoCells = {
|
|||
Class cls = [MWMUGCReviewCell class];
|
||||
auto c = static_cast<MWMUGCReviewCell *>(
|
||||
[tableView dequeueReusableCellWithCellClass:cls indexPath:indexPath]);
|
||||
[c configWithReview:static_cast<MWMUGCReview *>([ugc reviewWithIndex:indexPath.row])
|
||||
onUpdate:onUpdate];
|
||||
auto review = static_cast<MWMUGCReview *>([ugc reviewWithIndex:indexPath.row]);
|
||||
[c configWithReview:review
|
||||
isExpanded:[ugc isExpanded:review]
|
||||
onUpdate:^{
|
||||
[ugc markExpanded:review];
|
||||
onUpdate();
|
||||
}];
|
||||
return c;
|
||||
}
|
||||
case ReviewRow::MoreReviews:
|
||||
|
|
|
@ -30,6 +30,7 @@ MWMUGCRatingValueType * ratingValueType(float rating)
|
|||
|
||||
@interface MWMUGCViewModel ()
|
||||
@property(copy, nonatomic) MWMVoidBlock refreshCallback;
|
||||
@property(strong, nonatomic) NSMutableDictionary *expandedReviews;
|
||||
@end
|
||||
|
||||
@implementation MWMUGCViewModel
|
||||
|
@ -44,6 +45,7 @@ MWMUGCRatingValueType * ratingValueType(float rating)
|
|||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
_expandedReviews = [[NSMutableDictionary alloc] initWithCapacity: 1];
|
||||
m_ugc = ugc;
|
||||
m_ugcUpdate = update;
|
||||
[self fillReviewRows];
|
||||
|
@ -113,6 +115,16 @@ MWMUGCRatingValueType * ratingValueType(float rating)
|
|||
rating:ratingValueType(review.m_rating)];
|
||||
}
|
||||
|
||||
- (BOOL)isExpanded:(id<MWMReviewProtocol> _Nonnull) review {
|
||||
NSString *key = [[NSString alloc] initWithFormat:@"%@%lu", review.date, (unsigned long)[review.text hash]];
|
||||
return _expandedReviews[key] == nil ? NO : YES;
|
||||
}
|
||||
|
||||
- (void)markExpanded:(id<MWMReviewProtocol> _Nonnull) review {
|
||||
NSString *key = [[NSString alloc] initWithFormat:@"%@%lu", review.date, (unsigned long)[review.text hash]];
|
||||
_expandedReviews[key] = @YES;
|
||||
}
|
||||
|
||||
#pragma mark - Propertis
|
||||
|
||||
- (NSString *)reviewDate:(ugc::Time const &) time
|
||||
|
|
|
@ -3,4 +3,6 @@
|
|||
@protocol MWMReviewsViewModelProtocol
|
||||
- (NSInteger)numberOfReviews;
|
||||
- (id<MWMReviewProtocol> _Nonnull)reviewWithIndex:(NSInteger)index;
|
||||
- (BOOL)isExpanded:(id<MWMReviewProtocol> _Nonnull) review;
|
||||
- (void)markExpanded:(id<MWMReviewProtocol> _Nonnull) review;
|
||||
@end
|
||||
|
|
|
@ -15,6 +15,11 @@ final class ReviewsViewController: MWMTableViewController {
|
|||
super.viewDidLoad()
|
||||
registerCells()
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
tableView.refresh()
|
||||
}
|
||||
|
||||
private func registerCells() {
|
||||
[UGCYourReviewCell.self, UGCReviewCell.self].forEach {
|
||||
|
@ -31,11 +36,23 @@ final class ReviewsViewController: MWMTableViewController {
|
|||
switch cellModel {
|
||||
case let cellModel as UGCYourReview:
|
||||
let cell = tableView.dequeueReusableCell(withCellClass: UGCYourReviewCell.self, indexPath: indexPath) as! UGCYourReviewCell
|
||||
cell.config(yourReview: cellModel, onUpdate: tableView.refresh)
|
||||
cell.config(yourReview: cellModel,
|
||||
isExpanded: viewModel.isExpanded(cellModel),
|
||||
onUpdate: { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.viewModel.markExpanded(cellModel)
|
||||
self.tableView.refresh()
|
||||
})
|
||||
return cell
|
||||
case let cellModel as UGCReview:
|
||||
let cell = tableView.dequeueReusableCell(withCellClass: UGCReviewCell.self, indexPath: indexPath) as! UGCReviewCell
|
||||
cell.config(review: cellModel, onUpdate: tableView.refresh)
|
||||
cell.config(review: cellModel,
|
||||
isExpanded: viewModel.isExpanded(cellModel),
|
||||
onUpdate: { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.viewModel.markExpanded(cellModel)
|
||||
self.tableView.refresh()
|
||||
})
|
||||
return cell
|
||||
default: assert(false)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue