我们使用KIF进行功能测试,并使用元素的可访问性标签来确定发送事件的位置。我目前正在尝试测试UISegmentedControl的行为,但为了做到这一点,我需要为控件的不同段设置不同的可访问性标签。如何为特定细分设置辅助功能标签?
答案 0 :(得分:19)
正如Vertex所说,
<强> OBJ-C 强>
[[[self.segmentOutlet subviews] objectAtIndex:3] setAccessibilityLabel:@"GENERAL_SEGMENT"];
<强>迅速强>
self.segmentOutlet.subviews[3].accessibilityLabel = "GENERAL_SEGMENT"
一些建议,所以你不要像我一样疯狂:
答案 1 :(得分:10)
我刚刚开始使用KIF,所以我没有对此进行测试,但可能值得一试。我相信我很快就会遇到同样的问题,所以我很想知道它是否有效。
首先,UIAccessibility Protocol Reference在accessibilityLabel下有一条说明:
“如果您提供要在UISegmentedControl中显示的UIImage对象,则可以在每个图像上设置此属性,以确保可以正确访问这些段。”
所以,我想知道你是否也可以在每个NSString对象上设置accessibilityLabel,并且能够使用它来访问每个使用KIF的段。首先,您可以尝试创建几个字符串,设置其可访问性标签,并使用[[UISegmentedControl alloc] initWithItems:myStringArray];填充它。
请向我们介绍您的进度。我想知道这是怎么回事
答案 2 :(得分:9)
UISegmentedControl
的每个段都是UISegment
类实例,它是UIImageView
的子类。您可以通过subviews
的{{1}}属性访问这些实例,并尝试以编程方式为其添加辅助功能。
答案 3 :(得分:8)
这是一个老问题,但是为了防止其他人遇到这种情况,我发现这些网段会自动将可访问性标签指定为其文本。因此,如果添加了选项1和选项2的两个选项。请调用
[tester tapViewWithAccessibilityLabel:@"Option 2"];
成功选择了细分受众群。
答案 4 :(得分:4)
这是一个老问题,但是为了防止其他人遇到这种情况,我发现这些网段会自动将可访问性标签指定为其文字。
除了Stuart的回答之外,我发现在编写测试用例以启用“辅助功能检查器”时,它非常有用。在模拟器上(设置 - &gt;常规 - &gt;辅助功能 - &gt;辅助功能检查器)。您会惊讶地发现有多少元素已包含可访问性标签,例如标准iOS UI元素甚至第三方框架。
注意:手势现在会有所不同 - 点击查看辅助功能信息,点击两次即可选择。最小化“辅助功能检查器”窗口(通过点击X按钮)将使手势恢复正常。
答案 5 :(得分:4)
您不能依靠subviewsarray中的索引来获取位置。为了自定义单个子视图,我在设置任何属性之前将子视图在其X位置上进行排序。对于accesibilityLbel同样有效。
country_index = input('Country Code: ')
engine = create_engine('mysql+pymysql://user:pass@localhost:3306/{}'.format(country_index))
connection = engine.connect()
for lines in countryDict[country_index]:
lines.splitlines()
fredder = fred.get_series_all_releases(lines)
def Database_Table_Creator():
for table in countryDict[country_index]:
table.splitlines()
queryCreateTable = """CREATE TABLE `{}`(
DATE int,
REALTIME_START int,
VALUE int
)""".format(table)
connection.execute(queryCreateTable)
fredder.to_sql(
name = '{}'.format(table),
con = connection,
index = False,
if_exists='append',
chunksize = 500)
connection.close()
Database_Table_Creator()
答案 6 :(得分:4)
使用索引子视图的解决方案不起作用,因为您不能依赖正确的顺序,并且将很难更改段数。而且按原点排序不起作用,因为框架(至少对于当前版本而言)似乎始终为x:0。
我的解决方案:
(segmentedControl.accessibilityElement(at: 0) as? UIView)?.accessibilityLabel = "Custom VoiceOver Label 1"
(segmentedControl.accessibilityElement(at: 1) as? UIView)?.accessibilityLabel = "Custom VoiceOver Label 2"
(segmentedControl.accessibilityElement(at: 2) as? UIView)?.accessibilityLabel = "Custom VoiceOver Label 3"
似乎为我工作,并且命令正确。您也不依赖图像。也不是很漂亮,但可能比其他解决方案更可靠。
答案 7 :(得分:1)
如果不愿意设置辅助功能标签,则另一个选项可能是计算每个分段部分的位置并使用
[tester tapScreenAtPoint:segementPosition];
触发行动
答案 8 :(得分:1)
如果通过可访问性检查器查看分段控件,则会发现这些分段是UISegment对象。而且,它们原来是UISegmentedControl的直接子视图。这个事实表明,以下疯狂而又完全安全的Swift 4代码可以设置UISegmentedControl的各部分的可访问性标签:
let seg = // the UISegmentedControl
if let segclass = NSClassFromString("UISegment") {
let segments = seg.subviews.filter {type(of:$0) == segclass}
.sorted {$0.frame.minX < $1.frame.minX}
let labels = ["Previous article", "Next article"] // or whatever
for pair in zip(segments,labels) {
pair.0.accessibilityLabel = pair.1
}
}
答案 9 :(得分:1)
你们想看看苹果推荐如何做?
这很丑。
这来自this example:
func configureCustomSegmentsSegmentedControl() {
let imageToAccessibilityLabelMappings = [
"checkmark_icon": NSLocalizedString("Done", comment: ""),
"search_icon": NSLocalizedString("Search", comment: ""),
"tools_icon": NSLocalizedString("Settings", comment: "")
]
// Guarantee that the segments show up in the same order.
var sortedSegmentImageNames = Array(imageToAccessibilityLabelMappings.keys)
sortedSegmentImageNames.sort { lhs, rhs in
return lhs.localizedStandardCompare(rhs) == ComparisonResult.orderedAscending
}
for (idx, segmentImageName) in sortedSegmentImageNames.enumerated() {
let image = UIImage(named: segmentImageName)!
image.accessibilityLabel = imageToAccessibilityLabelMappings[segmentImageName]
customSegmentsSegmentedControl.setImage(image, forSegmentAt: idx)
}
customSegmentsSegmentedControl.selectedSegmentIndex = 0
customSegmentsSegmentedControl.addTarget(self,
action: #selector(SegmentedControlViewController.selectedSegmentDidChange(_:)),
for: .valueChanged)
}
他们将辅助功能标签应用于图像,然后附加图像。与above answer没什么不同。
答案 10 :(得分:0)
如已接受的答案中所述,在文本中添加 accessibilityLabel
应该可以解决问题:
let title0 = "Button1" as NSString
title0.accessibilityLabel = "MyButtonIdentifier1"
segmentedControl.setTitle("\(title0)", forSegmentAt: 0)
let title1 ="Button2" as NSString
title1.accessibilityLabel = "MyButtonIdentifier2"
segmentedControl.setTitle("\(title1)", forSegmentAt: 1)
答案 11 :(得分:0)
XCode 12 / iOS 14.3 / Swift 5
这是一篇旧帖子,但我在尝试为 UISegmentedControl 中的各个段设置可访问性提示时遇到了同样的问题。我也遇到了一些较旧的解决方案的问题。目前适用于我的应用的代码借鉴了诸如来自 matt 和 Ilker Baltaci 的回复,然后使用 UIView.description 混合在我自己的 hack 中。
首先,一些评论:
使用枚举设置段标题是依赖于在 UI 中手动设置的 X 排序的替代方法。如果您的枚举继承自 String 并采用 CaseIterable 和 RawRepresentable 协议,那么从枚举案例创建标题并根据段标题确定枚举案例就很简单了。
鉴于对 description.contains("UISegment") 的依赖,不保证以下内容将适用于框架的未来版本,但它对我有用。必须继续前进。
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// get only the UISegment items; ignore UIImageView
let segments = mySegmentedControl.subviews.compactMap(
{ $0.description.contains("UISegment") ? $0 : nil }
)
let sortedSegments = segments.sorted(
by: { $0.frame.origin.x < $1.frame.origin.x }
)
for i in 0 ..< sortedSegments.count {
let segment = sortedSegments[i]
// set .accessibilityHint or .accessibilityLabel by index
// or check for a segment title matching an enum case
// ...
}
}
关于私有 API 和拒绝
我指的是 @dan 2016 年 4 月在 Test if object is an instance of class UISegment 中发表的评论:
<块引用>这是一个私人课程。你可以用 [... isKindOfClass:NSClassFromString(@"UISegment")] 但这可能会让你 应用程序因使用私有 API 被拒绝或在将来停止工作,如果 苹果改变内部类名或结构。
还有: What exactly is a Private API, and why will Apple reject an iOS App if one is used?
“应用因非公开 api 被拒绝”:https://discussions.apple.com/thread/3838251
答案 12 :(得分:-1)
正如Vortex所说,数组从右到左,[0]从右边开始。您可以通过访问子视图来设置每个可访问性选项。由于子视图是可选的,因此最好先拉出子视图,然后分配所需的可访问性特征。简单的两个选项段控件的Swift 4示例:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
guard let rightSegment = segmentControl.subviews.first, let leftSegment = segmentControl.subviews.last else { return }
rightSegment.accessibilityLabel = "A label for the right segment."
rightSegment.accessibilityHint = "A hint for the right segment."
leftSegment.accessibilityLabel = "A label for the left segment."
leftSegment.accessibilityHint = "A hint for the left segment."
}