为 uibutton ios 使用表视图披露指示器样式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13836606/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Use table view disclosure indicator style for uibutton ios
提问by VBK
I have a custom view and i want to imitate the disclosure indicator found in table view cells. Is this possible ? Is there anyway of extracting that image ?
我有一个自定义视图,我想模仿在表格视图单元格中找到的披露指示符。这可能吗 ?无论如何提取该图像?
采纳答案by mevdev
Note that you must use a transparent background
请注意,您必须使用透明背景
Here's the best possible match I can get, in a photoshop file:
这是我能得到的最佳匹配,在 Photoshop 文件中:
Note that it includes the REAL iOS IMAGE (from a screenshot) underneath as a layer, so you can compare.
请注意,它包含下面作为图层的真实 iOS 图像(来自屏幕截图),因此您可以进行比较。
http://www.filedropper.com/fakearrowiosnov2013psd
http://www.filedropper.com/fakearrowiosnov2013psd
It seems like VBK wants the single chevron from the UITableView collection. Which is called 'Disclosure Indicator' as opposed to the one available from UIButton which is 'DetailDisclosure'.
似乎 VBK 想要 UITableView 集合中的单个 V 形。这被称为“披露指标”,而不是可从 UIButton 获得的“详细信息披露”。
I think you want something like this:
我想你想要这样的东西:
It is 50x80 with a transparent background. Use this image on top of a button or UIImageView. Resize it to whatever size you'd like your button to be. Apple recommends a hit target of no less than 40x40. I sized it to 10x16 in my storyboard, but I am using a transparent button overlay so the size doesn't matter.
它是具有透明背景的 50x80。在按钮或 UIImageView 顶部使用此图像。将其调整为您希望按钮的大小。Apple 建议命中目标不小于 40x40。我在情节提要中将其大小设置为 10x16,但我使用的是透明按钮覆盖层,因此大小无关紧要。
Image Mirror : http://imgur.com/X00qn0Z.png
镜像镜像:http: //imgur.com/X00qn0Z.png
Just note however this is not precisely the image used in iOS7. (Nov 2013.) To get the exact image, simply run an app in retina in your simulator, and make a screenshot.
但是请注意,这并不完全是 iOS7 中使用的图像。(2013 年 11 月。)要获得准确的图像,只需在模拟器中的 Retina 中运行应用程序,然后制作屏幕截图。
回答by Avario
This can be done entirely with code by placing a UITableViewCell
with the disclosure indicator within a UIButton
:
这可以完全通过代码完成,方法是在 a 中放置UITableViewCell
带有披露指示符的 a UIButton
:
UITableViewCell *disclosure = [[UITableViewCell alloc] init];
disclosure.frame = button.bounds;
disclosure.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
disclosure.userInteractionEnabled = NO;
[button addSubview:disclosure];
Swift:
迅速:
let disclosure = UITableViewCell()
disclosure.frame = button.bounds
disclosure.accessoryType = .disclosureIndicator
disclosure.isUserInteractionEnabled = false
button.addSubview(disclosure)
回答by fl034
Since Apple provides official iOS design resourcesfor different tools you can extract the chevron from there.
由于 Apple为不同的工具提供了官方 iOS 设计资源,因此您可以从那里提取 V 形符号。
Update
更新
Apple announced the icon font SF Symbolson the WWDC'19 keynote.
Apple在 WWDC'19 主题演讲中宣布了图标字体SF Symbols。
The SF Symbols companion app contains an icon called chevron.right
ready for you to use. You can also Specify the thickness of the icon.
SF Symbols 配套应用程序包含一个名为chevron.right
准备好供您使用的图标。您还可以指定图标的粗细。
回答by ale84
I made an entirely in code solution to draw arrows similar to UITableView disclosure indicator.
我制作了一个完全在代码中的解决方案来绘制类似于 UITableView 披露指示器的箭头。
It's used like this:
它是这样使用的:
let arrowImage = ArrowImageGenerator.generateArrow(withDirection: .down)
The default arrow looks the same as the default for the UITableView disclosure indicator. If you want you can customize direction (up, down, left, right), size, color and so on.
默认箭头看起来与 UITableView 显示指示器的默认箭头相同。如果需要,您可以自定义方向(上、下、左、右)、大小、颜色等。
Here is the code:
这是代码:
//
// ArrowImageGenerator.swift
//
// Created by Alessio Orlando on 07/10/15.
// Copyright ? 2015 Alessio Orlando. All rights reserved.
//
import Foundation
import UIKit
enum ArrowDirection {
case up
case down
case left
case right
}
class ArrowImageGenerator {
static var defaultColor: UIColor = {
let color = UIColor(red: 0.783922, green: 0.780392, blue: 0.8, alpha: 1)
return color
}()
class func generateArrow(withDirection direction: ArrowDirection = .right,
size: CGSize? = nil,
lineWidth: CGFloat = 2.0,
arrowColor: UIColor = ArrowImageGenerator.defaultColor,
backgroundColor: UIColor = UIColor.clear,
scale: CGFloat = UIScreen.main.scale)
-> UIImage? {
var actualSize: CGSize
if let size = size {
actualSize = size
}
else {
actualSize = defaultSize(for: direction)
}
let scaledSize = actualSize.applying(CGAffineTransform(scaleX: scale, y: scale))
let scaledLineWidth = lineWidth * scale
UIGraphicsBeginImageContext(CGSize(width: scaledSize.width, height: scaledSize.height))
defer {
UIGraphicsEndImageContext()
}
guard let context = UIGraphicsGetCurrentContext() else { return nil }
configureForArrowDrawing(context)
UIGraphicsPushContext(context)
strokeArrow(context, size: scaledSize, arrowColor: arrowColor, backgroundColor: backgroundColor, lineWidth: scaledLineWidth, direction: direction)
UIGraphicsPopContext()
guard let outputImage = UIGraphicsGetImageFromCurrentImageContext(),
let quartzImage = context.makeImage() else {
return nil
}
let scaledImage = UIImage(cgImage: quartzImage, scale: scale, orientation: outputImage.imageOrientation)
return scaledImage
}
private class func generateResizableArrow(_ arrowImage: UIImage, direction: ArrowDirection) -> UIImage {
var edgeInset: UIEdgeInsets?
switch direction {
case .up:
edgeInset = UIEdgeInsets(top: 11, left: 0, bottom: 1, right: 0)
case .down:
edgeInset = UIEdgeInsets(top: 1, left: 0, bottom: 11, right: 0)
case .left:
edgeInset = UIEdgeInsets(top: 1, left: 11, bottom: 1, right: 0)
case .right:
edgeInset = UIEdgeInsets(top: 1, left: 0, bottom: 1, right: 11)
}
let resizableImage = arrowImage.resizableImage(withCapInsets: edgeInset!)
return resizableImage
}
private class func configureForArrowDrawing(_ context: CGContext) {
context.setBlendMode(CGBlendMode.normal)
context.setAllowsAntialiasing(true)
context.setShouldAntialias(true)
}
private class func strokeArrow(_ context: CGContext, size: CGSize, arrowColor: UIColor, backgroundColor: UIColor, lineWidth: CGFloat = 1.0, direction: ArrowDirection) {
backgroundColor.setFill()
UIRectFill(CGRect(origin: CGPoint(x: 0, y: 0), size: size))
arrowColor.setStroke()
context.setLineWidth(lineWidth)
let lineWidthOffset = lineWidth / 2 // needed to make the arrow pointy.
switch direction {
case .up:
context.move(to: CGPoint(x: size.width, y: size.height))
context.addLine(to: CGPoint(x: size.width / 2, y: 0 + lineWidthOffset))
context.addLine(to: CGPoint(x: 0, y: size.height))
case .down:
context.move(to: CGPoint(x: size.width, y: 0))
context.addLine(to: CGPoint(x: size.width / 2, y: size.height - lineWidthOffset))
context.addLine(to: CGPoint(x: 0, y: 0))
case .left:
context.move(to: CGPoint(x: size.width, y: 0))
context.addLine(to: CGPoint(x: lineWidthOffset, y: size.height / 2))
context.addLine(to: CGPoint(x: size.width, y: size.height))
case .right:
context.move(to: CGPoint(x: 0, y: 0))
context.addLine(to: CGPoint(x: size.width - lineWidthOffset, y: size.height / 2))
context.addLine(to: CGPoint(x: 0, y: size.height))
}
context.strokePath()
}
class func defaultSize(for direction: ArrowDirection) -> CGSize {
switch direction {
case .up, .down:
return CGSize(width: 12, height: 7)
case .left, .right:
return CGSize(width: 7, height: 12)
}
}
}
Here is the complete gist: github gist
这是完整的要点:github gist
回答by Despotovic
What I like to do is to draw it using UIBezierPath
. This gives me a freedom to resize if I want to, without loosing clarity. And it also gives me an opportunity to change the colour later on if that's what I need without a photo editor.The principle is generic and applicable to any given path. The usage is quite simple:
我喜欢做的是使用UIBezierPath
. 如果我愿意,这让我可以自由调整大小,而不会失去清晰度。如果这是我在没有照片编辑器的情况下所需要的,它也让我有机会在以后更改颜色。该原则是通用的,适用于任何给定的路径。用法很简单:
//suppose we want to apply disclosure arrow image to this button:
@IBOutlet weak var btnDisclosure: UIButton!
All I need to do now is:
我现在需要做的就是:
//get an image from UIBezierPath, resize it for the button and stroke with white:
let arrowImage = UIImage.imageWithBezierPath(UIBezierPath.disclosureArrowPath().scaleToAspectFitRect(CGRect(x: 0, y: 0, width: 22, height: 22)), fillColor: UIColor.clearColor(), strokeColor: UIColor.whiteColor())
//assign disclosure arrow image to the button:
btnDisclosure.setImage(arrowImage, forState: .Normal)
So, a piece of code for drawing the UIBezierPath which looks like disclosure button:
所以,一段用于绘制 UIBezierPath 的代码,看起来像公开按钮:
extension UIBezierPath
{
///Disclosure arrow path. Use scaleToAspectFitRect to resize it to any given rect.
class func disclosureArrowPath() -> UIBezierPath
{
//// arrow Drawing
let arrowPath = UIBezierPath()
arrowPath.moveToPoint(CGPointMake(4, 4))
arrowPath.addLineToPoint(CGPointMake(26.5, 25.24))
arrowPath.addLineToPoint(CGPointMake(4, 47.5))
arrowPath.lineWidth = 3
return arrowPath
}
///Makes a path scalable to any size.
///- parameter newRect: The path will be resized to aspect fit into this rectangle.
func scaleToAspectFitRect(newRect: CGRect) -> UIBezierPath
{
var scaleFactor : CGFloat = 1.0
//this is probably only the case of scale factor < 1:
if bounds.width > bounds.height
{
//fit witdth:
scaleFactor = newRect.width/bounds.width
}
else
{
//fit height:
scaleFactor = newRect.height/bounds.height
}
//scale to aspect fill rect:
self.applyTransform(CGAffineTransformMakeScale(scaleFactor, scaleFactor))
return self
}
}
Next, you need a way to get the UIImage
out of UIBezierPath
. Again, you could add extension to UIImage that will do this like so:
接下来,你需要一种方式来获得的UIImage
出来的UIBezierPath
。同样,您可以向 UIImage 添加扩展,它会像这样执行此操作:
extension UIImage
{
///Custom fill and stroke colours for our image based on UIBezierPath
class func imageWithBezierPath(path: UIBezierPath, fillColor: UIColor, strokeColor: UIColor) -> UIImage
{
//enlarge the rect so that stroke line is not clipped:
let rect = CGRectInset(path.bounds, -path.lineWidth / 2, -path.lineWidth / 2)
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0) //size of the image, opaque, and scale (set to screen default with 0)
let bezierLayer = CAShapeLayer()
bezierLayer.path = path.CGPath;
bezierLayer.fillColor = fillColor.CGColor
bezierLayer.strokeColor = strokeColor.CGColor
bezierLayer.lineWidth = path.lineWidth;
let imgViewTmp = UIImageView(frame: path.bounds)
imgViewTmp.layer.addSublayer(bezierLayer);
imgViewTmp.layer.renderInContext(UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
//UIGraphicsEndImageContext()
return image
}
}
It may seem as an overkill for this specific task, but it's generic. And it's really handy if you deal a lot with resizing, trying to figure out the right design etc.
对于这项特定任务来说,这似乎有点矫枉过正,但它是通用的。如果你经常处理调整大小、试图找出正确的设计等,这真的很方便。
回答by Trevor Mayhew
You can extract the graphic images from the Xcode Simulator using this Xcode project - https://github.com/0xced/iOS-Artwork-Extractor
您可以使用此 Xcode 项目从 Xcode Simulator 中提取图形图像 - https://github.com/0xced/iOS-Artwork-Extractor
回答by sarge
This worked for me:
这对我有用:
UITableViewCell *disclosure = [[UITableViewCell alloc] init];
disclosure.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
for (UIView*v1 in disclosure.subviews)
{
if ([v1 isKindOfClass:[UIButton class]])
{
for (UIView*v2 in v1.subviews)
{
if ([v2 isKindOfClass:[UIImageView class]])
{
return ((UIImageView*)v2).image;
}
}
}
}
回答by ben
For Xamarin.iOS
对于 Xamarin.iOS
//create your button
var systolicWell = new UIButton(UIButtonType.RoundedRect);
systolicWell.BackgroundColor = UIColor.White;
//create the UITableViewCell
var systolicDisclosure = new UITableViewCell();
systolicDisclosure.Accessory = UITableViewCellAccessory.DisclosureIndicator;
systolicDisclosure.UserInteractionEnabled = false;
//add the button, then the UITableViewCell to the View
View.AddSubviews(systolicWell, systolicDisclosure);
//using FluentLayout https://github.com/slodge/Cirrious.FluentLayout
View.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
View.AddConstraints(
systolicWell.AtTopOf(View).Plus(5),
systolicWell.Width().EqualTo().WidthOf(View),
systolicWell.Height().EqualTo(10),
systolicDisclosure.WithSameTop(systolicWell),
systolicDisclosure.WithSameWidth(systolicWell),
systolicDisclosure.WithSameHeight(systolicWell));
回答by khanbdse
Swift3 / Swift4:
斯威夫特3 / 斯威夫特4:
disclosure indicator for button
按钮的显示指示器
let disclosureIndicator = UITableViewCell(style: .value1,
reuseIdentifier: nil)
let theWidth = UIScreen.main.bounds.width
let theHeight = yourButton.frame.height
yourButton.frame = CGRect(0,0, theWidth, theHeight)
disclosureIndicator.textLabel?.text = "title"
disclosureIndicator.detailTextLabel?.textColor = .black
disclosureIndicator.detailTextLabel?.text = "subtitle"
disclosureIndicator.accessoryType = .disclosureIndicator
disclosureIndicator.isUserInteractionEnabled = false
disclosureIndicator.frame = yourButton.bounds
yourButton.addSubview(disclosureIndicator)
add this extension for CGRect
为 CGRect 添加这个扩展
extension CGRect {
init(_ x:CGFloat, _ y:CGFloat, _ w:CGFloat, _ h:CGFloat) {
self.init(x:x, y:y, width:w, height:h)
}
}
回答by Abz Ios
You can add any custom image on the right side of UITableViewCell with a single line of Code:
您可以使用一行代码在 UITableViewCell 的右侧添加任何自定义图像:
Try This:
尝试这个:
-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.accessoryView = [[UIImageView alloc]initWithImage:
[UIImage imageNamed:@"blueButton.png"]];
}