Apple 更改 UI 的各个方面并不罕见。例如,“系统”字体在 iOS 版本之间已经更改了几次。在这种情况下,复选标记附件图像的位置似乎已在附件视图空间中左对齐(在 iOS 13 中)。
虽然您经常希望在 Apple 进行更改时更改您的 UI 元素(一个很好的例子是 UISegmentedControl),以便您的应用程序界面与操作系统匹配,但有时您不要。
在这种情况下,为了在 iOS 版本中获得最一致的外观,明智的做法是使用完全自定义的 UI 实现。
这是一个使用 PDF 作为复选标记图像的示例(因此我们可以保留矢量缩放),并将其 Render As 属性设置为 Template Image 使其符合色调着色。
首先,它在 Storyboard 中的外观如下:
我们将使用一个自定义单元类并覆盖它的accessoryType 属性:
class CustomCheckedCell: UITableViewCell {
@IBOutlet var leftLabel: UILabel!
@IBOutlet var rightLabel: UILabel!
@IBOutlet var myAccessoryView: UIImageView!
override var accessoryType: UITableViewCell.AccessoryType {
set {
myAccessoryView.alpha = newValue == .none ? 0.0 : 1.0
}
get {
return .none
}
}
override func awakeFromNib() {
super.awakeFromNib()
// we use contrasting colors to design the cell in Storyboard
// so set all backgrounds to clear at run-time
guard let lView = leftLabel.superview, let rView = rightLabel.superview else {
return
}
[lView, rView, leftLabel, rightLabel].forEach {
$0?.backgroundColor = .clear
}
}
}
我们现在可以使用默认的cell.accessoryType = .checkmark 或cell.accessoryType = .none 来显示/隐藏复选标记图像而不影响单元格的布局。
这是一个示例控制器类:
class CustomCheckedCellTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
// we can set the table view's tint color here (tint's our custom checkMark accessory)
tableView.tintColor = .red
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 30
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .checkmark
}
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .none
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cCell = tableView.dequeueReusableCell(withIdentifier: "CustomCheckedCell", for: indexPath) as! CustomCheckedCell
cCell.leftLabel.text = "Left \(indexPath.row)"
cCell.rightLabel.text = "Right \(indexPath.row)"
cCell.accessoryType = (tableView.indexPathForSelectedRow == indexPath) ? .checkmark : .none
return cCell
}
}
输出如下所示:
这里是故事板源代码:
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="KbA-Q0-LNC">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Custom Checked Cell Table View Controller-->
<scene sceneID="DAq-F3-sy8">
<objects>
<tableViewController id="qt8-QK-wnn" customClass="CustomCheckedCellTableViewController" customModule="iOS9SDK" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" keyboardDismissMode="onDrag" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="2Gh-42-LWt">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="CustomCheckedCell" rowHeight="56" id="r8I-XK-VkK" customClass="CustomCheckedCell" customModule="iOS9SDK" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" width="375" height="56"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="r8I-XK-VkK" id="MvA-eu-x6f">
<rect key="frame" x="0.0" y="0.0" width="375" height="56"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="mQ2-DJ-vUS">
<rect key="frame" x="16" y="0.0" width="311" height="56"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bfe-Sh-FxV" userLabel="LView">
<rect key="frame" x="0.0" y="0.0" width="200.5" height="56"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label 1" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Hhj-4f-3ME">
<rect key="frame" x="0.0" y="10" width="200.5" height="36"/>
<color key="backgroundColor" red="0.99953407049999998" green="0.98835557699999999" blue="0.47265523669999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="0.0" green="0.97680455450000003" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="Hhj-4f-3ME" firstAttribute="top" secondItem="bfe-Sh-FxV" secondAttribute="top" constant="10" id="BXa-Av-XMu"/>
<constraint firstAttribute="trailing" secondItem="Hhj-4f-3ME" secondAttribute="trailing" id="ND3-SS-NJN"/>
<constraint firstItem="Hhj-4f-3ME" firstAttribute="leading" secondItem="bfe-Sh-FxV" secondAttribute="leading" id="fhX-ir-pnY"/>
<constraint firstAttribute="bottom" secondItem="Hhj-4f-3ME" secondAttribute="bottom" constant="10" id="jCn-Ib-SDq"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ydx-kR-Ui2" userLabel="RView">
<rect key="frame" x="210.5" y="0.0" width="100.5" height="56"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label 2" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vaR-rB-U1a">
<rect key="frame" x="0.0" y="10" width="100.5" height="36"/>
<color key="backgroundColor" red="0.99953407049999998" green="0.98835557699999999" blue="0.47265523669999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="0.0" green="0.97680455450000003" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="vaR-rB-U1a" firstAttribute="top" secondItem="ydx-kR-Ui2" secondAttribute="top" constant="10" id="5LB-SK-csH"/>
<constraint firstAttribute="bottom" secondItem="vaR-rB-U1a" secondAttribute="bottom" constant="10" id="ghm-bd-7PC"/>
<constraint firstAttribute="trailing" secondItem="vaR-rB-U1a" secondAttribute="trailing" id="rIn-3p-Lpj"/>
<constraint firstItem="vaR-rB-U1a" firstAttribute="leading" secondItem="ydx-kR-Ui2" secondAttribute="leading" id="z1q-yz-bd6"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstItem="ydx-kR-Ui2" firstAttribute="width" secondItem="bfe-Sh-FxV" secondAttribute="width" multiplier="0.5" id="4h1-AF-V9L"/>
</constraints>
</stackView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="myCheckmark" translatesAutoresizingMaskIntoConstraints="NO" id="s8x-tM-09v">
<rect key="frame" x="339" y="17" width="20" height="20"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="4UJ-FQ-7yW"/>
<constraint firstAttribute="width" secondItem="s8x-tM-09v" secondAttribute="height" multiplier="1:1" id="bVw-JC-DCh"/>
</constraints>
<preferredSymbolConfiguration key="preferredSymbolConfiguration" weight="semibold"/>
</imageView>
</subviews>
<constraints>
<constraint firstItem="s8x-tM-09v" firstAttribute="leading" secondItem="mQ2-DJ-vUS" secondAttribute="trailing" constant="12" id="G9K-If-FTj"/>
<constraint firstItem="mQ2-DJ-vUS" firstAttribute="top" secondItem="MvA-eu-x6f" secondAttribute="top" id="HNe-Ks-vip"/>
<constraint firstAttribute="trailingMargin" secondItem="s8x-tM-09v" secondAttribute="trailing" id="M5d-Rz-1R2"/>
<constraint firstItem="mQ2-DJ-vUS" firstAttribute="leading" secondItem="MvA-eu-x6f" secondAttribute="leadingMargin" id="RCj-FT-gww"/>
<constraint firstAttribute="bottom" secondItem="mQ2-DJ-vUS" secondAttribute="bottom" id="azO-kX-4jB"/>
<constraint firstItem="s8x-tM-09v" firstAttribute="centerY" secondItem="mQ2-DJ-vUS" secondAttribute="centerY" constant="-1" id="qpV-6I-bLK"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="leftLabel" destination="Hhj-4f-3ME" id="WQS-bJ-KeJ"/>
<outlet property="myAccessoryView" destination="s8x-tM-09v" id="hUo-ed-Kyz"/>
<outlet property="rightLabel" destination="vaR-rB-U1a" id="RXC-UG-g5P"/>
</connections>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="qt8-QK-wnn" id="aMA-fV-5cb"/>
<outlet property="delegate" destination="qt8-QK-wnn" id="S0n-bN-MLJ"/>
</connections>
</tableView>
<navigationItem key="navigationItem" id="kxZ-av-xIt"/>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="qxa-2p-Cxd" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1556" y="830.73463268365822"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="d0B-12-bYa">
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="KbA-Q0-LNC" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="jcB-K3-ueL">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
<connections>
<segue destination="qt8-QK-wnn" kind="relationship" relationship="rootViewController" id="rwh-Te-ifH"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="5gD-zl-juz" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="616.79999999999995" y="830.73463268365822"/>
</scene>
</scenes>
<resources>
<image name="myCheckmark" width="50" height="50"/>
</resources>
</document>
以及我们自定义复选标记图像的 PDF 文件(我只是将它放在一个不相关的 GitHub 存储库中,因为我们无法在此处 pst pdf 文件):
https://github.com/DonMag/PDFImagePanZoom/blob/master/myCheckmark.pdf
当您将 pdf 文件添加到资产目录时,不要忘记设置渲染为、保留矢量数据和单一比例: