- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个带有自己的.xib 的自定义类。我正在尝试合并 IBInspectable 以更改 IB 中其背景和 subview 背景的颜色。
在IB,当我离开'Custom Class'
空白,并添加用户定义的运行时属性 'bgColor'
然后尝试运行应用程序,我得到 "...this class is not key value coding-compliant for the key bgColor."
该应用程序运行时不会崩溃,但不会将颜色应用于 View 。
当我设置 'Custom Class'
至"AxesView"
运行,应用程序崩溃,"Thread 1: EXC_BAD_ACCESS (code=2, address)"
并突出显示 "guard let view = Self.nib.instantiate..."
行在 func setupFromNib()
在 NibLoadableExtension.swift
有没有办法让这些东西一起工作,或者这是一个非此即彼的情况?
在 View Controller 中:
var axesView = AxesView()
override func viewDidLoad() {
super.viewDidLoad()
axesView.frame = self.view.bounds
self.view.addSubview(axesView)
}
var axesView = AxesView()
override func viewDidLoad() {
super.viewDidLoad()
axesView.frame = self.view.bounds
axesView.bgColor = .clear
axesView.lineColor = .red
self.view.addSubview(axesView)
axesView.contentView.translatesAutoresizingMaskIntoConstraints = false
axesView.contentView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0).isActive = true
axesView.contentView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0).isActive = true
axesView.contentView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0).isActive = true
axesView.contentView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0).isActive = true
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first! as UITouch
let p = touch.location(in: self.view)
axesView.vLine.center.x = p.x
axesView.hLine.center.y = p.y
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first! as UITouch
let p = touch.location(in: self.view)
axesView.vLine.center.x = p.x
axesView.hLine.center.y = p.y
self.view.setNeedsDisplay()
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
touchesMoved(touches, with: event)
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
touchesEnded(touches, with: event)
}
@IBDesignable class AxesView: UIView, NibLoadable {
@IBOutlet var contentView: UIView!
@IBOutlet weak var hLine: UIView!
@IBOutlet weak var vLine: UIView!
@IBInspectable var bgColor: UIColor = UIColor.white {
didSet {
contentView.backgroundColor = bgColor
}
}
@IBInspectable var lineColor: UIColor = UIColor.cyan {
didSet {
hLine.backgroundColor = lineColor
vLine.backgroundColor = lineColor
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setupFromNib()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupFromNib()
}
}
public protocol NibLoadable {
static var nibName: String { get }
}
public extension NibLoadable where Self: UIView {
static var nibName: String {
return String(describing: Self.self) // defaults to the name of the class implementing this protocol.
}
static var nib: UINib {
let bundle = Bundle(for: Self.self)
return UINib(nibName: Self.nibName, bundle: bundle)
}
func setupFromNib() {
guard let view = Self.nib.instantiate(withOwner: self, options: nil).first as? UIView else { fatalError("Error loading \(self) from nib") }
addSubview(view)
}
}
最佳答案
您的代码工作正常(大部分情况下)。
确保您已在正确的对象上设置类:
更改您的 setupFromNib()
作用于:
func setupFromNib() {
guard let view = Self.nib.instantiate(withOwner: self, options: nil).first as? UIView else { fatalError("Error loading \(self) from nib") }
addSubview(view)
view.frame = self.bounds
view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
// layout code...
}
class AxesTestViewController: UIViewController {
var axesView = AxesView()
override func viewDidLoad() {
super.viewDidLoad()
axesView.frame = self.view.bounds
axesView.bgColor = .blue
axesView.lineColor = .red
self.view.addSubview(axesView)
}
}
@IBDesignable
带有“可拖动”十字线的 xib。
.constant
在
中心X 和
中心Y 移动线条。我还移动了您的
touches...
funcs 在自定义 View 中使事情变得更有条理。
NibLoadable
代码(我将您的控件重命名为
TapAxesView
以进行比较):
public protocol NibLoadable {
static var nibName: String { get }
}
public extension NibLoadable where Self: UIView {
static var nibName: String {
return String(describing: Self.self) // defaults to the name of the class implementing this protocol.
}
static var nib: UINib {
let bundle = Bundle(for: Self.self)
return UINib(nibName: Self.nibName, bundle: bundle)
}
func setupFromNib() {
guard let view = Self.nib.instantiate(withOwner: self, options: nil).first as? UIView else { fatalError("Error loading \(self) from nib") }
addSubview(view)
view.backgroundColor = .clear
view.frame = self.bounds
view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
}
}
@IBDesignable
class TapAxesView: UIView, NibLoadable {
@IBOutlet var hLine: UIView!
@IBOutlet var vLine: UIView!
@IBOutlet var vLineCenterX: NSLayoutConstraint!
@IBOutlet var hLineCenterY: NSLayoutConstraint!
@IBInspectable var bgColor: UIColor = UIColor.white {
didSet {
self.backgroundColor = bgColor
}
}
@IBInspectable var lineColor: UIColor = UIColor.cyan {
didSet {
hLine.backgroundColor = lineColor
vLine.backgroundColor = lineColor
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setupFromNib()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupFromNib()
}
func updateCenter(_ point: CGPoint) -> Void {
// prevent centers from moving outside the bounds
let halfW = (bounds.size.width / 2.0)
let halfH = (bounds.size.height / 2.0)
let x = point.x - halfW
let y = point.y - halfH
vLineCenterX.constant = min(max(x, -halfW), halfW)
hLineCenterY.constant = min(max(y, -halfH), halfH)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first! as UITouch
let p = touch.location(in: self)
updateCenter(p)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first! as UITouch
let p = touch.location(in: self)
updateCenter(p)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
touchesMoved(touches, with: event)
}
}
class TapAxesTestViewController: UIViewController {
var axesView = TapAxesView()
override func viewDidLoad() {
super.viewDidLoad()
axesView.frame = self.view.bounds
axesView.bgColor = .clear
axesView.lineColor = .red
self.view.addSubview(axesView)
axesView.translatesAutoresizingMaskIntoConstraints = false
axesView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0).isActive = true
axesView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0).isActive = true
axesView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0).isActive = true
axesView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0).isActive = true
}
}
TapAxesView.xib
的来源文件:
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15705" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="TapAxesView" customModule="MiniScratch" customModuleProvider="target">
<connections>
<outlet property="hLine" destination="wry-9o-V8F" id="uCc-eL-sSS"/>
<outlet property="hLineCenterY" destination="Txd-hz-fX2" id="OUH-HO-ghG"/>
<outlet property="vLine" destination="x0E-M7-ETl" id="BaY-4q-4RA"/>
<outlet property="vLineCenterX" destination="pAM-XU-BDo" id="fgf-lE-dn3"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="375" height="382"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wry-9o-V8F">
<rect key="frame" x="0.0" y="189" width="375" height="4"/>
<color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="4" id="OqP-vn-hAj"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="x0E-M7-ETl">
<rect key="frame" x="185.5" y="0.0" width="4" height="382"/>
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="width" constant="4" id="cqZ-JL-4vH"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="wry-9o-V8F" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="Txd-hz-fX2"/>
<constraint firstItem="wry-9o-V8F" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="bcB-iZ-vbV"/>
<constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="x0E-M7-ETl" secondAttribute="bottom" id="hfl-4K-VZq"/>
<constraint firstItem="wry-9o-V8F" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="ma5-u8-0U4"/>
<constraint firstItem="x0E-M7-ETl" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="pAM-XU-BDo"/>
<constraint firstItem="x0E-M7-ETl" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" id="z8W-cZ-2Bi"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
<point key="canvasLocation" x="138.40000000000001" y="24.287856071964018"/>
</view>
</objects>
</document>
@IBDesignable
通过
查看仅代码 ... 没有
xib
需要文件(或 Nib 加载)。此外,这使用
CALayer
对于“十字线”而不是 subview 。使其“重量更轻”。
@IBDesignable
class LayerAxesView: UIView {
var hLine: CALayer = CALayer()
var vLine: CALayer = CALayer()
var curX: CGFloat = -1.0
var curY: CGFloat = -1.0
let lineWidth: CGFloat = 4.0
@IBInspectable var bgColor: UIColor = UIColor.white {
didSet {
self.backgroundColor = bgColor
}
}
@IBInspectable var lineColor: UIColor = UIColor.cyan {
didSet {
hLine.backgroundColor = lineColor.cgColor
vLine.backgroundColor = lineColor.cgColor
}
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
override func prepareForInterfaceBuilder() {
commonInit()
}
func commonInit() -> Void {
if hLine.superlayer == nil {
layer.addSublayer(hLine)
layer.addSublayer(vLine)
hLine.backgroundColor = lineColor.cgColor
vLine.backgroundColor = lineColor.cgColor
backgroundColor = bgColor
}
}
override func layoutSubviews() {
// if curX and curY have not yet been set,
// such as on init or when used in Storyboard / IB,
// initialize to center of view
if curX == -1 {
curX = bounds.midX
curY = bounds.midY
}
hLine.frame = CGRect(x: bounds.minX, y: curY - lineWidth * 0.5, width: bounds.maxX, height: lineWidth)
vLine.frame = CGRect(x: curX - lineWidth * 0.5, y: bounds.minY, width: lineWidth, height: bounds.maxY)
}
func updateCenter(_ point: CGPoint) -> Void {
// prevent centers from moving outside the bounds
curX = max(min(bounds.maxX, point.x), bounds.minX)
curY = max(min(bounds.maxY, point.y), bounds.minY)
// disable CALayer's built-in animation
CATransaction.begin()
CATransaction.setDisableActions(true)
setNeedsLayout()
layoutIfNeeded()
CATransaction.commit()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first! as UITouch
let p = touch.location(in: self)
updateCenter(p)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first! as UITouch
let p = touch.location(in: self)
updateCenter(p)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
touchesMoved(touches, with: event)
}
}
class TapAxesTestViewController: UIViewController {
var axesView: LayerAxesView = {
let v = LayerAxesView()
v.translatesAutoresizingMaskIntoConstraints = false
v.lineColor = .red
v.bgColor = UIColor.blue.withAlphaComponent(0.5)
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(axesView)
// respect safe area
let g = view.safeAreaLayoutGuide
// constrain axesView to safe area with 40-pts "padding"
NSLayoutConstraint.activate([
axesView.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
axesView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0),
axesView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -40.0),
axesView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -40.0),
])
}
}
关于ios - IBInspectable 出现问题并从 xib 为 Interface Builder 加载 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60851269/
编写一个仅用于集中其他接口(interface)的接口(interface)是好的做法还是坏的做法? interface InterfaceA : InterfaceB, InterfaceC { }
有没有一种方法可以确定具体类型从任意接口(interface)列表?我知道类型转换,但我想知道所有满意的接口(interface)。 例如,给定: type Mover interface { Mo
我正在尝试制作斐波那契堆。 (在我正在上的算法课中多次提到它们,我想检查一下。)我希望堆使用任何类型的节点,所以我定义了一个 Node 接口(interface): package node type
这是我的代码: type IA interface { FB() IB } type IB interface { Bar() string } type A struct {
示例 A: // pseudo code interface IFoo { void bar(); } class FooPlatformA : IFoo { void bar() {
合并它编译的 leppies 反馈 - 但 IMO 有一些缺点,我希望编译器强制每个子类定义它们自己的 Uri 属性。现在的代码: [] type UriUserControl() = inh
我正在构建一个项目,该项目从用户那里获取一个术语,然后执行谷歌搜索并返回一个 json 格式的标题列表。 我正在使用 serpwow API 来执行谷歌搜索并试图解析响应。 但是我收到的错误是: pa
我只想在其他接口(interface)中实现某些接口(interface),我不希望它们能够被类直接继承。 提前致谢! 最佳答案 您不能在 C# 中执行此操作 - 任何类都可以实现它有权访问的任何接口
我是 Go 的新手,还有一些我还没有掌握的技巧 例如,我有一个可以这样调用的函数: myVar.InitOperation("foo",Operator.EQUAL,"bar") myVar.Init
我有一个通用接口(interface)来描述对输出流的访问,如下所示: interface IOutput { function writeInteger(aValue:Int):Void;
我正在做一个项目,我想通过某种接口(interface)(最好是 USB)将光电探测器电路安装到计算机上。但是,由于我是新手,所以我不知道应该朝哪个方向处理这个问题。假设我有一个带有 USB 连接的光
背景 我正在尝试创建一个简单的应用程序,以真正理解DDD + TDD + etc的整个堆栈。我的目标是在运行时动态注入DAL存储库类。这让我 域和应用程序服务层可测试。我打算用“穷人的DI”来完成 现
在 Java 中,接口(interface)扩展接口(interface)是完全合法的。 UML 中的这种关系看起来像“扩展”关系(实线、闭合、未填充的箭头)还是“实现”关系(虚线、闭合、未填充的箭头
我想创建一个具有相等和比较函数默认实现的接口(interface)。 如果我从类型 IKeyable 中删除所有内容除了Key成员,只要我不添加默认实现,它就是一个有效的接口(interface)。从
COM 中的双接口(interface)是能够通过 DispInterface 或 VTable 方法访问的接口(interface)。 现在有人可以告诉我这两种方法之间到底有什么区别吗? 我认为 V
我有一个类方法,它返回一个可以迭代的员工列表。返回列表的最佳方式是什么?通常我只返回一个 ArrayList。然而,据我了解,界面更适合这种类型的操作。哪个是最好使用的界面?另外,为什么返回接口(in
我想从包装类外部实例化一个内部非静态接口(interface)。 这可能吗? 考虑以下代码: shared class AOuterClass() { Integer val = 3; shared
我为一个类编写了一个接口(interface),如下所示: public interface IGenericMultipleRepository { Lazy> addresses { ge
我是 UML 的初学者,现在我正在创建一个序列图,问题是我想根据用户输入实现 DAO 接口(interface)。如何在时序图中正确绘制以实现接口(interface)。 最佳答案 您不会在 SD 上
要使用 jsr 303 验证创建有条件验证的组,请将接口(interface)类传递给注释,如下所示: @NotEmpty (groups={UpdateValue.class}) 我有很多不同的接口
我是一名优秀的程序员,十分优秀!