mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-14 17:23:25 +01:00
- Feature: Markdown view integration complete (if issues arrise can fix it asap)
This commit is contained in:
@@ -43,7 +43,8 @@ final class AppContentViewController: UITableViewController
|
||||
}()
|
||||
|
||||
@IBOutlet private var subtitleLabel: UILabel!
|
||||
@IBOutlet private var descriptionTextView: CollapsingTextView!
|
||||
// @IBOutlet private var descriptionTextView: CollapsingTextView!
|
||||
@IBOutlet private var descriptionTextView: CollapsingMarkdownView!
|
||||
// @IBOutlet private var versionDescriptionTextView: CollapsingTextView!
|
||||
@IBOutlet private var versionDescriptionTextView: CollapsingMarkdownView!
|
||||
@IBOutlet private var versionLabel: UILabel!
|
||||
@@ -55,37 +56,6 @@ final class AppContentViewController: UITableViewController
|
||||
|
||||
@IBOutlet private(set) var appDetailCollectionViewController: AppDetailCollectionViewController!
|
||||
@IBOutlet private var appDetailCollectionViewHeightConstraint: NSLayoutConstraint!
|
||||
//
|
||||
// override func viewDidLoad()
|
||||
// {
|
||||
// super.viewDidLoad()
|
||||
//
|
||||
// self.tableView.contentInset.bottom = 20
|
||||
//
|
||||
// self.subtitleLabel.text = self.app.subtitle
|
||||
// self.descriptionTextView.text = self.app.localizedDescription
|
||||
//
|
||||
// if let version = self.app.latestAvailableVersion
|
||||
// {
|
||||
// self.versionDescriptionTextView.text = version.localizedDescription ?? "nil"
|
||||
// self.versionLabel.text = String(format: NSLocalizedString("Version %@", comment: ""), version.localizedVersion)
|
||||
// self.versionDateLabel.text = Date().relativeDateString(since: version.date)
|
||||
// self.sizeLabel.text = self.byteCountFormatter.string(fromByteCount: version.size)
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// self.versionDescriptionTextView.text = "nil"
|
||||
// self.versionLabel.text = nil
|
||||
// self.versionDateLabel.text = nil
|
||||
// self.sizeLabel.text = self.byteCountFormatter.string(fromByteCount: 0)
|
||||
// }
|
||||
//
|
||||
// self.descriptionTextView.maximumNumberOfLines = 5
|
||||
// self.descriptionTextView.moreButton.addTarget(self, action: #selector(AppContentViewController.toggleCollapsingSection(_:)), for: .primaryActionTriggered)
|
||||
//
|
||||
// self.versionDescriptionTextView.maximumNumberOfLines = 3
|
||||
// self.versionDescriptionTextView.toggleButton.addTarget(self, action: #selector(AppContentViewController.toggleCollapsingSection(_:)), for: .primaryActionTriggered)
|
||||
// }
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
@@ -93,7 +63,8 @@ final class AppContentViewController: UITableViewController
|
||||
self.tableView.contentInset.bottom = 20
|
||||
|
||||
self.subtitleLabel.text = self.app.subtitle
|
||||
self.descriptionTextView.text = self.app.localizedDescription
|
||||
let desc = self.app.localizedDescription
|
||||
self.descriptionTextView.text = desc
|
||||
|
||||
if let version = self.app.latestAvailableVersion {
|
||||
self.versionDescriptionTextView.text = version.localizedDescription ?? "nil"
|
||||
@@ -107,20 +78,11 @@ final class AppContentViewController: UITableViewController
|
||||
self.sizeLabel.text = ByteCountFormatter.string(fromByteCount: 0, countStyle: .file)
|
||||
}
|
||||
|
||||
// Set maximum number of lines (no extra target-action needed)
|
||||
self.descriptionTextView.maximumNumberOfLines = 5
|
||||
self.versionDescriptionTextView.maximumNumberOfLines = 3
|
||||
self.versionDescriptionTextView.maximumNumberOfLines = 5
|
||||
|
||||
// Instead of adding another target for toggle, set the didToggleCollapse callback:
|
||||
self.descriptionTextView.moreButton.addTarget(self, action: #selector(AppContentViewController.toggleCollapsingSection(_:)), for: .primaryActionTriggered)
|
||||
|
||||
self.versionDescriptionTextView.didToggleCollapse = { [weak self] in
|
||||
guard let self = self else { return }
|
||||
UIView.animate(withDuration: 0.25) {
|
||||
self.tableView.beginUpdates()
|
||||
self.tableView.endUpdates()
|
||||
}
|
||||
}
|
||||
self.descriptionTextView.toggleButton.addTarget(self, action: #selector(AppContentViewController.toggleCollapsingSection(_:)), for: .primaryActionTriggered)
|
||||
self.versionDescriptionTextView.toggleButton.addTarget(self, action: #selector(AppContentViewController.toggleCollapsingSection(_:)), for: .primaryActionTriggered)
|
||||
}
|
||||
|
||||
override func viewDidLayoutSubviews()
|
||||
@@ -199,37 +161,18 @@ private extension AppContentViewController
|
||||
|
||||
switch sender
|
||||
{
|
||||
case self.descriptionTextView.moreButton:
|
||||
case self.descriptionTextView.toggleButton:
|
||||
indexPath = IndexPath(row: Row.description.rawValue, section: 0)
|
||||
// Toggle the state for the text view
|
||||
self.descriptionTextView.isCollapsed.toggle()
|
||||
|
||||
case self.versionDescriptionTextView.toggleButton:
|
||||
indexPath = IndexPath(row: Row.versionDescription.rawValue, section: 0)
|
||||
// Toggle the state for the markdown view
|
||||
self.versionDescriptionTextView.isCollapsed.toggle()
|
||||
|
||||
|
||||
default: return
|
||||
}
|
||||
|
||||
// First apply the new state to the views
|
||||
switch Row.allCases[indexPath.row] {
|
||||
case .description:
|
||||
self.descriptionTextView.setNeedsLayout()
|
||||
self.descriptionTextView.layoutIfNeeded()
|
||||
|
||||
case .versionDescription:
|
||||
self.versionDescriptionTextView.setNeedsLayout()
|
||||
self.versionDescriptionTextView.layoutIfNeeded()
|
||||
|
||||
default: break
|
||||
}
|
||||
|
||||
// Then reload the row with animation
|
||||
UIView.animate(withDuration: 0.25) {
|
||||
// Force table view to recalculate height
|
||||
self.tableView.beginUpdates()
|
||||
self.tableView.endUpdates()
|
||||
// Disable animations to prevent some potentially strange ones.
|
||||
UIView.performWithoutAnimation {
|
||||
self.tableView.reloadRows(at: [indexPath], with: .none)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,7 +287,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="98"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" editable="NO" text="Hello Me" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="Pyt-8D-BZA" customClass="CollapsingTextView" customModule="SideStore" customModuleProvider="target">
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" editable="NO" text="Hello Me" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="Pyt-8D-BZA" customClass="CollapsingMarkdownView" customModule="SideStore" customModuleProvider="target">
|
||||
<rect key="frame" x="20" y="20" width="335" height="34"/>
|
||||
<color key="backgroundColor" name="Background"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
|
||||
@@ -13,21 +13,18 @@ final class CollapsingTextView: UITextView
|
||||
var isCollapsed = true {
|
||||
didSet {
|
||||
guard self.isCollapsed != oldValue else { return }
|
||||
self.shouldResetLayout = true
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
}
|
||||
|
||||
var maximumNumberOfLines = 2 {
|
||||
didSet {
|
||||
self.shouldResetLayout = true
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
}
|
||||
|
||||
var lineSpacing: Double = 2 {
|
||||
didSet {
|
||||
self.shouldResetLayout = true
|
||||
|
||||
if #available(iOS 16, *)
|
||||
{
|
||||
@@ -42,7 +39,6 @@ final class CollapsingTextView: UITextView
|
||||
|
||||
override var text: String! {
|
||||
didSet {
|
||||
self.shouldResetLayout = true
|
||||
|
||||
guard #available(iOS 16, *) else { return }
|
||||
self.updateText()
|
||||
@@ -51,9 +47,6 @@ final class CollapsingTextView: UITextView
|
||||
|
||||
let moreButton = UIButton(type: .system)
|
||||
|
||||
private var shouldResetLayout: Bool = false
|
||||
private var previousSize: CGSize?
|
||||
|
||||
override init(frame: CGRect, textContainer: NSTextContainer?)
|
||||
{
|
||||
super.init(frame: frame, textContainer: textContainer)
|
||||
@@ -115,45 +108,39 @@ final class CollapsingTextView: UITextView
|
||||
height: font.lineHeight)
|
||||
self.moreButton.frame = moreButtonFrame
|
||||
|
||||
if self.shouldResetLayout || self.previousSize != self.bounds.size
|
||||
if self.isCollapsed
|
||||
{
|
||||
if self.isCollapsed
|
||||
let boundingSize = self.attributedText.boundingRect(with: CGSize(width: self.textContainer.size.width, height: .infinity), options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil)
|
||||
let maximumCollapsedHeight = font.lineHeight * Double(self.maximumNumberOfLines) + self.lineSpacing * Double(self.maximumNumberOfLines - 1)
|
||||
|
||||
if boundingSize.height.rounded() > maximumCollapsedHeight.rounded()
|
||||
{
|
||||
let boundingSize = self.attributedText.boundingRect(with: CGSize(width: self.textContainer.size.width, height: .infinity), options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil)
|
||||
let maximumCollapsedHeight = font.lineHeight * Double(self.maximumNumberOfLines) + self.lineSpacing * Double(self.maximumNumberOfLines - 1)
|
||||
self.textContainer.maximumNumberOfLines = self.maximumNumberOfLines
|
||||
|
||||
if boundingSize.height.rounded() > maximumCollapsedHeight.rounded()
|
||||
{
|
||||
self.textContainer.maximumNumberOfLines = self.maximumNumberOfLines
|
||||
|
||||
var exclusionFrame = moreButtonFrame
|
||||
exclusionFrame.origin.y += self.moreButton.bounds.midY
|
||||
exclusionFrame.size.width = self.bounds.width // Extra wide to make sure it wraps to next line.
|
||||
self.textContainer.exclusionPaths = [UIBezierPath(rect: exclusionFrame)]
|
||||
|
||||
self.moreButton.isHidden = false
|
||||
}
|
||||
else
|
||||
{
|
||||
self.textContainer.maximumNumberOfLines = 0 // Fixes last line having slightly smaller line spacing.
|
||||
self.textContainer.exclusionPaths = []
|
||||
|
||||
self.moreButton.isHidden = true
|
||||
}
|
||||
var exclusionFrame = moreButtonFrame
|
||||
exclusionFrame.origin.y += self.moreButton.bounds.midY
|
||||
exclusionFrame.size.width = self.bounds.width // Extra wide to make sure it wraps to next line.
|
||||
self.textContainer.exclusionPaths = [UIBezierPath(rect: exclusionFrame)]
|
||||
|
||||
self.moreButton.isHidden = false
|
||||
}
|
||||
else
|
||||
{
|
||||
self.textContainer.maximumNumberOfLines = 0
|
||||
self.textContainer.maximumNumberOfLines = 0 // Fixes last line having slightly smaller line spacing.
|
||||
self.textContainer.exclusionPaths = []
|
||||
|
||||
self.moreButton.isHidden = true
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self.textContainer.maximumNumberOfLines = 0
|
||||
self.textContainer.exclusionPaths = []
|
||||
|
||||
self.invalidateIntrinsicContentSize()
|
||||
self.moreButton.isHidden = true
|
||||
}
|
||||
|
||||
self.shouldResetLayout = false
|
||||
self.previousSize = self.bounds.size
|
||||
self.invalidateIntrinsicContentSize()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -235,6 +235,7 @@ private extension MyAppsViewController
|
||||
cell.layoutMargins.right = self.view.layoutMargins.right
|
||||
|
||||
cell.tintColor = app.tintColor ?? .altPrimary
|
||||
cell.versionDescriptionTextView.maximumNumberOfLines = 2
|
||||
cell.versionDescriptionTextView.text = latestSupportedVersion.localizedDescription ?? "nil"
|
||||
|
||||
cell.bannerView.iconImageView.image = nil
|
||||
|
||||
Reference in New Issue
Block a user