Xcode:AccessoryType.checkmark 将其他视图推向左侧
Posted
技术标签:
【中文标题】Xcode:AccessoryType.checkmark 将其他视图推向左侧【英文标题】:Xcode: AccessoryType.checkmark pushes other views to the left 【发布时间】:2019-04-18 12:41:58 【问题描述】:Xcode 10、Swift 5、ios 12
我的应用包含 3 个ViewControllers
:
-
登录
表格视图
TableView中单行数据的详细信息
如果您在 ViewController 3 中编辑并保存数据并使用“返回”按钮(通过NavigationController
)返回 ViewController 2,则会在 TableView 的相应行中添加一个复选标记。
问题是这个复选标记将其他所有内容推到左侧,即使我为它留了一些空间:
设置:
水平StackView
有 2 个子视图,每个子视图 1 个标签
StackView 设置为“填充”
第二个子视图是第一个子视图的一半
左边领先 10 点,右边落后 40 点(也已经测试了 100 点,但没有变化)
当我创建它们时,我已经尝试将AccessoryType.none
添加到每一行(如建议的here) - 像这样:
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell
cell.setLabels("Label1","Label2")
tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.none
//cell.accessoryType = UITableViewCell.AccessoryType.none //This doesn't work either
return cell
但它没有被添加(与其他类型相同)。
我该如何解决这个问题?是否可以在仍然使用AccessoryType
的同时将复选标记设置为“隐藏”其他所有内容?
【问题讨论】:
您链接到的答案说使用 空附件视图 ...这与设置AccessoryType.none
不同。跨度>
@DonMag 哦。我怎么做?库中没有布局元素。奇怪的是,在设置过程中添加复选标记似乎不起作用。我注意到可以直接在单元格的“属性检查器”中添加一个附件,然后通过“色调”将其颜色更改为背景颜色,然后将色调更改为例如红色使复选标记可见。但我不太喜欢这个解决方案,因为它是半硬编码到背景颜色的。
我也遇到了一些奇怪的事情:如果第 0 行得到复选标记,第 11 行也会出现(与 1&12、2&13、...相同)。我的 func 肯定只被调用一次(我在开头添加了一个“打印”)并且 IndexPath 只说类似[0,2]
(第 2 行)的内容。
好的,这取决于模拟器的大小:它只发生在不可见的行上,所以对于 iPhone SE 模拟器,除了第 0 行(0-9是可见的,几乎没有 10。对于 iPhone 7,它是第 16 行(0-11 可见,12 只有一半),而对于 iPhone Xs,它根本不会发生。更奇怪的是:当我上下滚动时,标记会四处移动(总是下降一排)!
细胞被重复使用,所以你不能只是“设置复选标记”。您必须将其设置为.checkmark
或.none
每次。
【参考方案1】:
在您创建用于处理单元格的 UITableViewCell 中,添加以下函数。此函数测试当前单元格是否设置了附件类型,如果没有,则将单元格缩小 40pts,从而使带有和不带有附件的单元格在自动布局中具有相同的大小。
override var frame: CGRect
get
return super.frame
set (newFrame)
var frame = newFrame
if self.accessoryType == .none
frame.size.width -= 40
super.frame = frame
【讨论】:
【参考方案2】:对此有多种方法,但我认为最好的方法是将图像视图添加到您的自定义单元格并使用您自己的复选标记图像。
然后当您在cellForRowAt
中设置标签的文本时,而不是在需要的地方设置cell.accessoryType = .checkmark
,而是将图像视图的图像设置为您自己的复选标记图像(或者,将图像视图.alpha
设置为@987654330 @(未显示)或1
(显示)):
当然,你会使用自己的比我为这个例子抓到的那个更好复选标记图像:)
编辑:
如果要使用淡色,可以将图像设置为“模板”图像。在你的单元格初始化中是这样的:
checkImageView.image = checkImageView.image?.withRenderingMode(.alwaysTemplate)
checkImageView.tintColor = .red
编辑 2:
如果您不想使用自定义图像,则可以将堆栈视图的后沿限制为 Cell,而不是限制在单元格的 Content View: p>
40-pts 看起来不错,但您需要确认这一点,并且您需要仔细检查不同设备上的间距是否相同(视网膜与非视网膜等)。
另外,设置附件的正确方法是将其设置在cellForRowAt
中的单元格上。假设(基于您的 cmets)您保留对所选行的引用 - 假设它是
var currentSelectedIndexPath: IndexPath!
你想做类似这样的事情:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCustomCell", for: indexPath) as! MyCustomCell
cell.leftLabel.text = "Left \(indexPath.row)"
cell.rightLabel.text = "Right \(indexPath.row)"
cell.accessoryType = (indexPath == currentSelectedIndexPath) ? .checkmark : .none
return cell
编辑 3:
您需要对表格视图、单元格、选择、数据跟踪等进行更多阅读...
但是,这里有一个完整的例子。
首先,故事板。创建一个新的单视图项目。右键单击情节提要并选择
Open As -> Source Code
删除那里的内容,然后粘贴以下内容:
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="KbA-Q0-LNC">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Selected Row Table View Controller-->
<scene sceneID="DAq-F3-sy8">
<objects>
<tableViewController id="qt8-QK-wnn" customClass="SelectedRowTableViewController" customModule="XC10SWScratch" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" 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" />
<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="MyCustomCell" rowHeight="56" id="r8I-XK-VkK" customClass="MyCustomCell" customModule="XC10SWScratch" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" />
<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" />
<autoresizingMask key="autoresizingMask"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="mQ2-DJ-vUS">
<rect key="frame" x="10" y="0.0" />
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bfe-Sh-FxV">
<rect key="frame" x="0.0" y="0.0" />
<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="10" y="10" />
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<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" constant="10" id="ND3-SS-NJN"/>
<constraint firstItem="Hhj-4f-3ME" firstAttribute="leading" secondItem="bfe-Sh-FxV" secondAttribute="leading" constant="10" 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">
<rect key="frame" x="220" y="0.0" />
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label 2" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vaR-rB-U1a">
<rect key="frame" x="10" y="10" />
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<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" constant="10" id="rIn-3p-Lpj"/>
<constraint firstItem="vaR-rB-U1a" firstAttribute="leading" secondItem="ydx-kR-Ui2" secondAttribute="leading" constant="10" 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>
</subviews>
<constraints>
<constraint firstItem="mQ2-DJ-vUS" firstAttribute="top" secondItem="MvA-eu-x6f" secondAttribute="top" id="HNe-Ks-vip"/>
<constraint firstItem="mQ2-DJ-vUS" firstAttribute="leading" secondItem="MvA-eu-x6f" secondAttribute="leading" constant="10" id="RCj-FT-gww"/>
<constraint firstAttribute="bottom" secondItem="mQ2-DJ-vUS" secondAttribute="bottom" id="azO-kX-4jB"/>
</constraints>
</tableViewCellContentView>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="mQ2-DJ-vUS" secondAttribute="trailing" constant="40" id="UCo-0w-3ki"/>
</constraints>
<connections>
<outlet property="leftLabel" destination="Hhj-4f-3ME" id="WQS-bJ-KeJ"/>
<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="20" />
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
<connections>
<segue destination="qt8-QK-wnn" kind="relationship" relationship="rootViewController" id="YsO-wj-izb"/>
</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>
</document>
然后您可以右键单击情节提要并选择
Open As -> Interface Builder - Storyboard
查看布局。
接下来,将默认ViewController.swift
的内容替换为以下代码:
import UIKit
class MyCustomCell: UITableViewCell
@IBOutlet var leftLabel: UILabel!
@IBOutlet var rightLabel: UILabel!
class SelectedRowTableViewController: UITableViewController
override func viewDidLoad()
super.viewDidLoad()
tableView.estimatedRowHeight = 60.0
// MARK: - Table view data source
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)
let cell = tableView.cellForRow(at: indexPath)
cell?.accessoryType = .checkmark
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath)
let cell = tableView.cellForRow(at: indexPath)
cell?.accessoryType = .none
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCustomCell", for: indexPath) as! MyCustomCell
cell.leftLabel.text = "Left \(indexPath.row)"
cell.rightLabel.text = "Right \(indexPath.row)"
cell.accessoryType = (tableView.indexPathForSelectedRow == indexPath) ? .checkmark : .none
return cell
然后您应该能够运行该应用程序。检查自定义单元格上的约束,并查看代码(非常、非常基本)以查看选中标记是如何在选定行上设置的(并在未选定行上删除),以及滚动时它是如何正确设置的。
【讨论】:
感谢您的解决方案。如果我找不到使用AccessoryType
正确执行此操作的方法(我喜欢您可以轻松地使用它们更改颜色),我将尝试使用图像。您是否碰巧知道如何使用AccessoryType
来解决问题(并解决我在上一条评论中描述的问题)?
查看我的编辑,了解如何为自定义复选标记图像着色。
@Neph - 查看我的“编辑 2”
40pts 应该绰绰有余,我什至尝试了 100,但一切仍然被推到一边。约束是为 StackView 而不是 ContentView 设置的,它甚至不允许我为它或单元格本身添加约束(一切都变灰了)。在cellForRowAt
中设置AccessoryType 是否与在单元格的“属性检查器”的下拉菜单中选中复选标记相同?之后如何更改单元格的色调,使复选标记出现在右侧单元格旁边?我现在什至尝试保留对每个单元格的引用,但彩色复选标记仍在移动。
然后您需要向数据源添加一个 BOOL 元素,并根据“已检查”状态将其设置为 true 或 false。将cellForRowAt
更改为cell.accessoryType = (myData[indexPath.row].mySelectedState == true) ? .checkmark : .none
以上是关于Xcode:AccessoryType.checkmark 将其他视图推向左侧的主要内容,如果未能解决你的问题,请参考以下文章