2015-03-19 2 views
0

Я создаю собственный класс ячейки таблицы представления. Но у меня есть проблема.Неустранимая ошибка: init (coder :) не был реализован

Мой код:

import UIKit 

let incomingTag = 0, outgoingTag = 1 
let bubbleTag = 8 

class MessageCell: UITableViewCell { 

    let bubbleImageView: UIImageView 
    let messageLabel: UILabel 

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) { 
     bubbleImageView = UIImageView(image: bubbleImage.incoming, highlightedImage: bubbleImage.incomingHighlighed) 
     bubbleImageView.tag = bubbleTag 
     bubbleImageView.userInteractionEnabled = true // #CopyMesage 

     messageLabel = UILabel(frame: CGRectZero) 
     messageLabel.font = UIFont.systemFontOfSize(15) 
     messageLabel.numberOfLines = 0 
     messageLabel.userInteractionEnabled = false // #CopyMessage 

     super.init(style: .Default, reuseIdentifier: reuseIdentifier) 
     selectionStyle = .None 

     contentView.addSubview(bubbleImageView) 
     bubbleImageView.addSubview(messageLabel) 

     bubbleImageView.setTranslatesAutoresizingMaskIntoConstraints(false) 
     messageLabel.setTranslatesAutoresizingMaskIntoConstraints(false) 
     contentView.addConstraint(NSLayoutConstraint(item: bubbleImageView, attribute: .Left, relatedBy: .Equal, toItem: contentView, attribute: .Left, multiplier: 1, constant: 10)) 
     contentView.addConstraint(NSLayoutConstraint(item: bubbleImageView, attribute: .Top, relatedBy: .Equal, toItem: contentView, attribute: .Top, multiplier: 1, constant: 4.5)) 
     bubbleImageView.addConstraint(NSLayoutConstraint(item: bubbleImageView, attribute: .Width, relatedBy: .Equal, toItem: messageLabel, attribute: .Width, multiplier: 1, constant: 30)) 
     contentView.addConstraint(NSLayoutConstraint(item: bubbleImageView, attribute: .Bottom, relatedBy: .Equal, toItem: contentView, attribute: .Bottom, multiplier: 1, constant: -4.5)) 

     bubbleImageView.addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .CenterX, relatedBy: .Equal, toItem: bubbleImageView, attribute: .CenterX, multiplier: 1, constant: 3)) 
     bubbleImageView.addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .CenterY, relatedBy: .Equal, toItem: bubbleImageView, attribute: .CenterY, multiplier: 1, constant: -0.5)) 
     messageLabel.preferredMaxLayoutWidth = 218 
     bubbleImageView.addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .Height, relatedBy: .Equal, toItem: bubbleImageView, attribute: .Height, multiplier: 1, constant: -15)) 


    } 

    required init(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 





    func configureWithMessage(message: Message) { 
     messageLabel.text = message.text 

     if message.incoming != (tag == incomingTag) { 
      var layoutAttribute: NSLayoutAttribute 
      var layoutConstant: CGFloat 

      if message.incoming { 
       tag = incomingTag 
       bubbleImageView.image = bubbleImage.incoming 
       bubbleImageView.highlightedImage = bubbleImage.incomingHighlighed 
       messageLabel.textColor = UIColor.blackColor() 
       layoutAttribute = .Left 
       layoutConstant = 10 
      } else { // outgoing 
       tag = outgoingTag 
       bubbleImageView.image = bubbleImage.outgoing 
       bubbleImageView.highlightedImage = bubbleImage.outgoingHighlighed 
       messageLabel.textColor = UIColor.whiteColor() 
       layoutAttribute = .Right 
       layoutConstant = -10 
      } 

      let layoutConstraint: NSLayoutConstraint = bubbleImageView.constraints()[1] as NSLayoutConstraint // `messageLabel` CenterX 
      layoutConstraint.constant = -layoutConstraint.constant 

      let constraints: NSArray = contentView.constraints() 
      let indexOfConstraint = constraints.indexOfObjectPassingTest { (var constraint, idx, stop) in 
       return (constraint.firstItem as UIView).tag == bubbleTag && (constraint.firstAttribute == NSLayoutAttribute.Left || constraint.firstAttribute == NSLayoutAttribute.Right) 
      } 
      contentView.removeConstraint(constraints[indexOfConstraint] as NSLayoutConstraint) 
      contentView.addConstraint(NSLayoutConstraint(item: bubbleImageView, attribute: layoutAttribute, relatedBy: .Equal, toItem: contentView, attribute: layoutAttribute, multiplier: 1, constant: layoutConstant)) 
     } 
    } 

    // Highlight cell #CopyMessage 
    override func setSelected(selected: Bool, animated: Bool) { 
     super.setSelected(selected, animated: animated) 
     bubbleImageView.highlighted = selected 
    } 
} 

let bubbleImage = bubbleImageMake() 

func bubbleImageMake() -> (incoming: UIImage, incomingHighlighed: UIImage, outgoing: UIImage, outgoingHighlighed: UIImage) { 
    let maskOutgoing = UIImage(named: "MessageBubble")! 
    let maskIncoming = UIImage(CGImage: maskOutgoing.CGImage, scale: 2, orientation: .UpMirrored)! 

    let capInsetsIncoming = UIEdgeInsets(top: 17, left: 26.5, bottom: 17.5, right: 21) 
    let capInsetsOutgoing = UIEdgeInsets(top: 17, left: 21, bottom: 17.5, right: 26.5) 

    let incoming = coloredImage(maskIncoming, 229/255.0, 229/255.0, 234/255.0, 1).resizableImageWithCapInsets(capInsetsIncoming) 
    let incomingHighlighted = coloredImage(maskIncoming, 206/255.0, 206/255.0, 210/255.0, 1).resizableImageWithCapInsets(capInsetsIncoming) 
    let outgoing = coloredImage(maskOutgoing, 43/255.0, 119/255.0, 250/255.0, 1).resizableImageWithCapInsets(capInsetsOutgoing) 
    let outgoingHighlighted = coloredImage(maskOutgoing, 32/255.0, 96/255.0, 200/255.0, 1).resizableImageWithCapInsets(capInsetsOutgoing) 

    return (incoming, incomingHighlighted, outgoing, outgoingHighlighted) 
} 

func coloredImage(image: UIImage, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) -> UIImage! { 
    let rect = CGRect(origin: CGPointZero, size: image.size) 
    UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale) 
    let context = UIGraphicsGetCurrentContext() 
    image.drawInRect(rect) 
    CGContextSetRGBFillColor(context, red, green, blue, alpha) 
    CGContextSetBlendMode(context, kCGBlendModeSourceAtop) 
    CGContextFillRect(context, rect) 
    let result = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 
    return result 
} 

Мое приложение рушится с этой линией:

fatal error: init(coder:) has not been implemented: 

Как я могу предотвратить эту ошибку? Я использую swift.Что делать? Я исследовал stackoverflow, я нашел похожие вопросы, но я не мог решить эту проблему.

ответ

2

Реализация init(coder:) метода:

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

Более углубленный ответ может быть найден в another Stack Overflow answer.

Полный пример:

var bubbleImageView: UIImageView! 
var messageLabel: UILabel! 

override init(style: UITableViewCellStyle, reuseIdentifier: String?) { 
    super.init(style: style, reuseIdentifier: reuseIdentifier) 
    self.setup() 
} 

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

private func setup() { 
    bubbleImageView = UIImageView(image: bubbleImage.incoming, highlightedImage: bubbleImage.incomingHighlighed) 
     bubbleImageView.tag = bubbleTag 
     bubbleImageView.userInteractionEnabled = true // #CopyMesage 

     messageLabel = UILabel(frame: CGRectZero) 
     messageLabel.font = UIFont.systemFontOfSize(15) 
     messageLabel.numberOfLines = 0 
     messageLabel.userInteractionEnabled = false // #CopyMessage 

     selectionStyle = .None 

     contentView.addSubview(bubbleImageView) 
     bubbleImageView.addSubview(messageLabel) 

     bubbleImageView.setTranslatesAutoresizingMaskIntoConstraints(false) 
     messageLabel.setTranslatesAutoresizingMaskIntoConstraints(false) 
     contentView.addConstraint(NSLayoutConstraint(item: bubbleImageView, attribute: .Left, relatedBy: .Equal, toItem: contentView, attribute: .Left, multiplier: 1, constant: 10)) 
     contentView.addConstraint(NSLayoutConstraint(item: bubbleImageView, attribute: .Top, relatedBy: .Equal, toItem: contentView, attribute: .Top, multiplier: 1, constant: 4.5)) 
     bubbleImageView.addConstraint(NSLayoutConstraint(item: bubbleImageView, attribute: .Width, relatedBy: .Equal, toItem: messageLabel, attribute: .Width, multiplier: 1, constant: 30)) 
     contentView.addConstraint(NSLayoutConstraint(item: bubbleImageView, attribute: .Bottom, relatedBy: .Equal, toItem: contentView, attribute: .Bottom, multiplier: 1, constant: -4.5)) 

     bubbleImageView.addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .CenterX, relatedBy: .Equal, toItem: bubbleImageView, attribute: .CenterX, multiplier: 1, constant: 3)) 
     bubbleImageView.addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .CenterY, relatedBy: .Equal, toItem: bubbleImageView, attribute: .CenterY, multiplier: 1, constant: -0.5)) 
     messageLabel.preferredMaxLayoutWidth = 218 
     bubbleImageView.addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .Height, relatedBy: .Equal, toItem: bubbleImageView, attribute: .Height, multiplier: 1, constant: -15)) 
} 
+0

Я получаю ошибку компилятора: свойство «self.bubbleImageView» не инициализируется при super.init вызова – Okan

+2

Вы должны инициализировать все свойства во всех ваших 'init' методов. Одним из решений является создание нового метода, называемого «setup», и вызов этого из обоих методов «init». Затем измените свойства, чтобы они были явно развернуты, добавив '!' В конец своего типа. Вы можете найти дополнительную информацию о ошибке компилятора с помощью [другого ответа на переполнение стека] (http://stackoverflow.com/a/24021346/657676) –

+0

Можете привести пример? Я действительно новичок с быстрым. – Okan

Смежные вопросы