2017-06-16 5 views
1

J'ai écrit une classe de vue personnalisée nommée MyCustomView.swift avec MyCustomView.xib. Lorsque j'utiliseAffichage personnalisé ne s'affiche pas en ajoutant UIView dans le storyboard pour hériter de la classe personnalisée

let customView = MyCustomView(frame:.....) 
self.view.addSubView(customView) 

La vue personnalisée apparaît. Mais quand j'ajoute directement un UIView dans Storyboard, et que je choisis MyCustomView comme classe de Custom Class, il n'apparaît pas. Même si je définis la couleur de fond de l'UIView, cela ne fonctionne pas. Surtout quand j'annoter le MyCustomview avec @IBDesignable, deux showes d'avertissement d'erreur,

Failed to render and update auto layout status fo XXXViewController 
Failed to update auto layout status 

que ça veut dire que je devrais mettre la mise en page automatique pour l'affichage personnalisé en story-board?

C'est MyCustomView.class

import UIKit 
@IBDesignable 
class MyCustomView:UIView{ 
@IBOutlet weak var categoryLabel: UILabel! 

var category:String = ""{ 
    didSet{ 
     self.categoryLabel.text = category 
    } 
} 
var intro:String = "" 
var address:String = "" 
var distance:CGFloat = 0.0 


override init(frame: CGRect) { 
    super.init(frame: frame) 
    awakeFromNib() 
    print("\(#function)") 
} 
convenience init(){ 
    print("\(#function)") 
    self.init(frame:CGRect.zero) 
} 

required init?(coder aDecoder: NSCoder) { 
    print("\(#function)") 
    super.init(coder: aDecoder) 
    awakeFromNib() 

} 

override func awakeFromNib() { 
    super.awakeFromNib() 
    let view = Bundle.main.loadNibNamed("MyCustomView", owner: self, options: nil)?.first as! UIView 
    view.autoresizingMask = UIViewAutoresizing.flexibleWidth.union(.flexibleHeight) 
    addSubview(view) 
} 
override func layoutSubviews() { 
    super.layoutSubviews() 
} 

} 
+0

Veuillez ajouter du code pour votre classe 'MyCustomView'. comment vous ajoutez le fichier xib? – xmhafiz

+0

@hafiz Ceci est mon code MyCustomView.class –

+0

@Leo J'ai essayé ..... –

Répondre

1

Ce que vous devez faire est de préfixe @IBInspectable avant votre var s .

Voici un exemple: classe personnalisée: Rainbow.swift

import Foundation 
import UIKit 

@IBDesignable 
class Rainbow: UIView { 
    @IBInspectable var firstColor: UIColor = UIColor(red: (37.0/255.0), green: (252.0/255), blue: (244.0/255.0), alpha: 1.0) 
    @IBInspectable var secondColor: UIColor = UIColor(red: (171.0/255.0), green: (250.0/255), blue: (81.0/255.0), alpha: 1.0) 
    @IBInspectable var thirdColor: UIColor = UIColor(red: (238.0/255.0), green: (32.0/255), blue: (53.0/255.0), alpha: 1.0) 

    required init(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder)! 
    } 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
    } 

    func addOval(_ lineWidth: CGFloat, path: CGPath, strokeStart: CGFloat, strokeEnd: CGFloat, strokeColor: UIColor, fillColor: UIColor, shadowRadius: CGFloat, shadowOpacity: Float, shadowOffsset: CGSize) { 

     let arc = CAShapeLayer() 
     arc.lineWidth = lineWidth 
     arc.path = path 
     arc.strokeStart = strokeStart 
     arc.strokeEnd = strokeEnd 
     arc.strokeColor = strokeColor.cgColor 
     arc.fillColor = fillColor.cgColor 
     arc.shadowColor = UIColor.black.cgColor 
     arc.shadowRadius = shadowRadius 
     arc.shadowOpacity = shadowOpacity 
     arc.shadowOffset = shadowOffsset 
     layer.addSublayer(arc) 
    } 

    override func draw(_ rect: CGRect) { 
     // Add ARCs 
     self.addCirle(80, capRadius: 20, color: self.firstColor) 
     self.addCirle(150, capRadius: 20, color: self.secondColor) 
     self.addCirle(215, capRadius: 20, color: self.thirdColor) 
    } 

    func addCirle(_ arcRadius: CGFloat, capRadius: CGFloat, color: UIColor) { 
     let X = self.bounds.midX 
     let Y = self.bounds.midY 

     // Bottom Oval 
     let pathBottom = UIBezierPath(ovalIn: CGRect(x: (X - (arcRadius/2)), y: (Y - (arcRadius/2)), width: arcRadius, height: arcRadius)).cgPath 
     self.addOval(20.0, path: pathBottom, strokeStart: 0, strokeEnd: 0.5, strokeColor: color, fillColor: UIColor.clear, shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSize.zero) 

     // Middle Cap 
     let pathMiddle = UIBezierPath(ovalIn: CGRect(x: (X - (capRadius/2)) - (arcRadius/2), y: (Y - (capRadius/2)), width: capRadius, height: capRadius)).cgPath 
     self.addOval(0.0, path: pathMiddle, strokeStart: 0, strokeEnd: 1.0, strokeColor: color, fillColor: color, shadowRadius: 5.0, shadowOpacity: 0.5, shadowOffsset: CGSize.zero) 

     // Top Oval 
     let pathTop = UIBezierPath(ovalIn: CGRect(x: (X - (arcRadius/2)), y: (Y - (arcRadius/2)), width: arcRadius, height: arcRadius)).cgPath 
     self.addOval(20.0, path: pathTop, strokeStart: 0.5, strokeEnd: 1.0, strokeColor: color, fillColor: UIColor.clear, shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSize.zero) 

    } 
} 

Il tire Rainbow

Source: https://www.appcoda.com/ibdesignable-ibinspectable-tutorial/

Essayez d'ajouter ce code:

override func awakeFromNib() { 
     super.awakeFromNib() 
     xibSetup() 
    } 

    func xibSetup() { 
     guard let view = loadViewFromNib() else { return } 
     view.frame = bounds 
     view.autoresizingMask = 
        [.flexibleWidth, .flexibleHeight] 
     addSubview(view) 
     contentView = view 
    } 

    func loadViewFromNib() -> UIView? { 
     guard let nibName = nibName else { return nil } 
     let bundle = Bundle(for: type(of: self)) 
     let nib = UINib(nibName: nibName, bundle: bundle) 
     return nib.instantiate(
        withOwner: self, 
        options: nil).first as? UIView 
    } 
+0

Merci! Mais l'erreur a disparu, mais l'UIView ne montre toujours pas. Seulement par le code dans ViewController puis-je dessiner la vue. –

+0

Lorsque vous tracez une vue à l'aide du code, vous ne voyez les effets que lorsque vous exécutez votre projet. – Prashant

+0

Cliquez sur votre objet vue personnalisée et dans l'inspecteur Identité définissez le ** _ Module_ ** sur IBDesignable comme indiqué ici http://imgur.com/a/t3LJR – Prashant

0

Essayez retirer le @IBDesignable parce que Xcode recherche IBInspectable propriétés dans votre classe qui existent pas

+0

Vous avez raison. Mais ce n'est pas mon point clé. Sans \ @IBDesignable, l'uiview dans le storyboard ne peut toujours pas s'afficher. Je pense que le \ @IBDesignable juste dans un autre aspect montre ma vue personnalisée d'erreur d'utilisation. Mais le code by dans Viewcontroller la vue fonctionne bien. –

+0

@ 周雪静 mais cela supprime le droit '' Rétablir le rendu et mettre à jour la disposition automatique''. Ajouter la propriété 'IBInspectable' va probablement le rendre à votre storyboard – xmhafiz

+0

pas l'erreur disparaître mais la vue ne le fait pas. J'essaie alternativement d'utiliser le code pour dessiner en vue. Ça marche. Mais xib n'a pas –