Swift UIButton 子类未在设备或模拟器上显示
Swift UIButton Subclass not Showing on device or Simulator
我有以下代码并声明了 IBDesignable。
DrawRect 在 Interface Builder 中显示得非常好,但在模拟器或设备中完全没有显示。
有人知道为什么吗?
import UIKit
import QuartzCore
@IBDesignable class VideoButton: UIButton {
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func drawRect(rect: CGRect)
{
let color2 = UIColor(red: 0.500, green: 0.500, blue: 0.500, alpha: 0.000)
//// Oval Drawing
var ovalPath = UIBezierPath(ovalInRect: CGRectMake(frame.minX + floor(frame.width * 0.03571) + 0.5, frame.minY + floor(frame.height * 0.03571) + 0.5, floor(frame.width * 0.96429) - floor(frame.width * 0.03571), floor(frame.height * 0.96429) - floor(frame.height * 0.03571)))
color2.setFill()
ovalPath.fill()
UIColor.whiteColor().setStroke()
ovalPath.lineWidth = 3
ovalPath.stroke()
//// Rectangle Drawing
let rectanglePath = UIBezierPath(roundedRect: CGRectMake(frame.minX + floor(frame.width * 0.25714 + 0.5), frame.minY + floor(frame.height * 0.34286 + 0.5), floor(frame.width * 0.60000 + 0.5) - floor(frame.width * 0.25714 + 0.5), floor(frame.height * 0.64286 + 0.5) - floor(frame.height * 0.34286 + 0.5)), cornerRadius: 2)
color2.setFill()
rectanglePath.fill()
UIColor.whiteColor().setStroke()
rectanglePath.lineWidth = 3
rectanglePath.stroke()
//// Bezier Drawing
var bezierPath = UIBezierPath()
bezierPath.moveToPoint(CGPointMake(frame.minX + 0.61429 * frame.width, frame.minY + 0.50536 * frame.height))
bezierPath.addLineToPoint(CGPointMake(frame.minX + 0.75714 * frame.width, frame.minY + 0.34286 * frame.height))
bezierPath.addLineToPoint(CGPointMake(frame.minX + 0.75714 * frame.width, frame.minY + 0.64286 * frame.height))
bezierPath.addLineToPoint(CGPointMake(frame.minX + 0.61429 * frame.width, frame.minY + 0.50536 * frame.height))
bezierPath.closePath()
bezierPath.lineJoinStyle = kCGLineJoinRound;
color2.setFill()
bezierPath.fill()
UIColor.whiteColor().setStroke()
bezierPath.lineWidth = 3
bezierPath.stroke()
// }
}
}
您不应覆盖 drawRect:
的 UIButton 子类。没有必要;您可以使用其各种属性和方法自定义 UIButton 的外观。目前还不清楚你为什么要这样做。 (事实上,你 正在 这样做,而不是调用 super
,这可能解释了问题;但解决方案不是调用 super
,而是,不要一开始就这样做。)
将对 'frame' 的引用更改为 'rect',它应该在设备和模拟器中绘制。
我最近一直在尝试做类似的事情 - 创建一个 UIButton 的子class,覆盖 drawRect()
以绘制一个简单的自定义图标(我正在制作一个 play/stop 按钮,每次点击时在 "Play" 和 "Stop" 之间交替):
也许我对 iOS 的发展还不够了解,但为了回应其他答案和 older posts 在线不鼓励扩展 UIButton
class,我不明白为什么这是个坏主意。当然,您可以通过设置自定义背景图像来自定义按钮,但在我看来,这不如覆盖 drawRect
灵活(更不用说在您想更改某些内容时随时编辑按钮可能会很痛苦,因为您必须编辑实际图像而不是几行代码)。
我确定还有其他方法可以达到相同的结果(例如,通过自定义 UIView
侦听触摸事件来实现按钮),但我认为最干净、最简单的方法仍然是扩展 UIButton
class。毕竟是一个subclass itself of UIView
.
关于您的代码 - 它似乎在我的环境中正常工作,尽管我不得不稍微更改颜色以使其在白色背景下显示(即 UIColor.blackColor().setStroke()
而不是 UIColor.whiteColor().setStroke()
).另外,正如@Astrodan 提到的,使用 rect
而不是 frame
可能是个好主意,因为它已传递给您(尽管代码对我来说使用 frame
):
XCode 中的实时渲染故事板:
开启 iPhone 6 模拟器:
我有以下代码并声明了 IBDesignable。
DrawRect 在 Interface Builder 中显示得非常好,但在模拟器或设备中完全没有显示。
有人知道为什么吗?
import UIKit
import QuartzCore
@IBDesignable class VideoButton: UIButton {
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func drawRect(rect: CGRect)
{
let color2 = UIColor(red: 0.500, green: 0.500, blue: 0.500, alpha: 0.000)
//// Oval Drawing
var ovalPath = UIBezierPath(ovalInRect: CGRectMake(frame.minX + floor(frame.width * 0.03571) + 0.5, frame.minY + floor(frame.height * 0.03571) + 0.5, floor(frame.width * 0.96429) - floor(frame.width * 0.03571), floor(frame.height * 0.96429) - floor(frame.height * 0.03571)))
color2.setFill()
ovalPath.fill()
UIColor.whiteColor().setStroke()
ovalPath.lineWidth = 3
ovalPath.stroke()
//// Rectangle Drawing
let rectanglePath = UIBezierPath(roundedRect: CGRectMake(frame.minX + floor(frame.width * 0.25714 + 0.5), frame.minY + floor(frame.height * 0.34286 + 0.5), floor(frame.width * 0.60000 + 0.5) - floor(frame.width * 0.25714 + 0.5), floor(frame.height * 0.64286 + 0.5) - floor(frame.height * 0.34286 + 0.5)), cornerRadius: 2)
color2.setFill()
rectanglePath.fill()
UIColor.whiteColor().setStroke()
rectanglePath.lineWidth = 3
rectanglePath.stroke()
//// Bezier Drawing
var bezierPath = UIBezierPath()
bezierPath.moveToPoint(CGPointMake(frame.minX + 0.61429 * frame.width, frame.minY + 0.50536 * frame.height))
bezierPath.addLineToPoint(CGPointMake(frame.minX + 0.75714 * frame.width, frame.minY + 0.34286 * frame.height))
bezierPath.addLineToPoint(CGPointMake(frame.minX + 0.75714 * frame.width, frame.minY + 0.64286 * frame.height))
bezierPath.addLineToPoint(CGPointMake(frame.minX + 0.61429 * frame.width, frame.minY + 0.50536 * frame.height))
bezierPath.closePath()
bezierPath.lineJoinStyle = kCGLineJoinRound;
color2.setFill()
bezierPath.fill()
UIColor.whiteColor().setStroke()
bezierPath.lineWidth = 3
bezierPath.stroke()
// }
}
}
您不应覆盖 drawRect:
的 UIButton 子类。没有必要;您可以使用其各种属性和方法自定义 UIButton 的外观。目前还不清楚你为什么要这样做。 (事实上,你 正在 这样做,而不是调用 super
,这可能解释了问题;但解决方案不是调用 super
,而是,不要一开始就这样做。)
将对 'frame' 的引用更改为 'rect',它应该在设备和模拟器中绘制。
我最近一直在尝试做类似的事情 - 创建一个 UIButton 的子class,覆盖 drawRect()
以绘制一个简单的自定义图标(我正在制作一个 play/stop 按钮,每次点击时在 "Play" 和 "Stop" 之间交替):
也许我对 iOS 的发展还不够了解,但为了回应其他答案和 older posts 在线不鼓励扩展 UIButton
class,我不明白为什么这是个坏主意。当然,您可以通过设置自定义背景图像来自定义按钮,但在我看来,这不如覆盖 drawRect
灵活(更不用说在您想更改某些内容时随时编辑按钮可能会很痛苦,因为您必须编辑实际图像而不是几行代码)。
我确定还有其他方法可以达到相同的结果(例如,通过自定义 UIView
侦听触摸事件来实现按钮),但我认为最干净、最简单的方法仍然是扩展 UIButton
class。毕竟是一个subclass itself of UIView
.
关于您的代码 - 它似乎在我的环境中正常工作,尽管我不得不稍微更改颜色以使其在白色背景下显示(即 UIColor.blackColor().setStroke()
而不是 UIColor.whiteColor().setStroke()
).另外,正如@Astrodan 提到的,使用 rect
而不是 frame
可能是个好主意,因为它已传递给您(尽管代码对我来说使用 frame
):
XCode 中的实时渲染故事板:
开启 iPhone 6 模拟器: