【问题标题】:Changing property values when initialiser is called调用初始化程序时更改属性值
【发布时间】:2019-06-03 18:08:32
【问题描述】:

这是我上一个问题的跟进here

我正在使用MarkdownTextView 将基本降价添加到UITextViewTextViewMarkdownTextView 的子类。

在我之前的问题中,使用复制和粘贴时出现以下错误

致命错误:对类使用未实现的初始化程序“init()” MarkdownTextStorage

直到我将以下初始化程序添加到 MarkdownTextStorage

public override convenience init() {
    self.init(attributes: MarkdownAttributes())
}

public init(attributes: MarkdownAttributes = MarkdownAttributes()) {
    self.attributes = attributes
    super.init()
    commonInit()

    if let headerAttributes = attributes.headerAttributes {
        addHighlighter(MarkdownHeaderHighlighter(attributes: headerAttributes))
    }
    addHighlighter(MarkdownLinkHighlighter())
    addHighlighter(MarkdownListHighlighter(markerPattern: "[*+-]", attributes: attributes.unorderedListAttributes, itemAttributes: attributes.unorderedListItemAttributes))
    addHighlighter(MarkdownListHighlighter(markerPattern: "\\d+[.]", attributes: attributes.orderedListAttributes, itemAttributes: attributes.orderedListItemAttributes))

    // From markdown.pl v1.0.1 <http://daringfireball.net/projects/markdown/>

    // Code blocks
    addPattern("(?:\n\n|\\A)((?:(?:[ ]{4}|\t).*\n+)+)((?=^[ ]{0,4}\\S)|\\Z)", attributes.codeBlockAttributes)

    // Block quotes
    addPattern("(?:^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+", attributes.blockQuoteAttributes)

    // Se-text style headers
    // H1
    addPattern("^(?:.+)[ \t]*\n=+[ \t]*\n+", attributes.headerAttributes?.h1Attributes)

    // H2
    addPattern("^(?:.+)[ \t]*\n-+[ \t]*\n+", attributes.headerAttributes?.h2Attributes)

    // Emphasis
    addPattern("(\\*|_)(?=\\S)(.+?)(?<=\\S)\\1", attributesForTraits(.traitItalic, attributes.emphasisAttributes))

    // Strong
    addPattern("(\\*\\*|__)(?=\\S)(?:.+?[*_]*)(?<=\\S)\\1", attributesForTraits(.traitBold, attributes.strongAttributes))

    // Inline code
    addPattern("(`+)(?:.+?)(?<!`)\\1(?!`)", attributes.inlineCodeAttributes)
}

但是,一旦我这样做了,每次复制和粘贴时都会出现以下错误。

似乎每次用户复制和粘贴初始化程序时,都会在更改为ViewController 中设置的字体属性之前设置默认的MarkdownAttributes。此屏幕截图位于正在设置的文本属性之间。

这就是我在ViewController 中使用TextStorage 来设置文本属性的方式

let fonty = UIFont(name: font, size: fsize)

attributes.defaultAttributes[NSFontAttributeName] = fonty
attributes.orderedListAttributes?[NSFontAttributeName] = fonty
attributes.orderedListItemAttributes?[NSFontAttributeName] = fonty
attributes.unorderedListAttributes?[NSFontAttributeName] = fonty
attributes.unorderedListItemAttributes?[NSFontAttributeName] = fonty

let textStorage = MarkdownTextStorage(attributes: attributes)

这是MarkdownAttributes 结构

public struct MarkdownAttributes {

let fonty = UIFont(name: "OpenSans", size: 30)

public var defaultAttributes: TextAttributes = [
    NSFontAttributeName: UIFont.preferredFont(forTextStyle: UIFontTextStyle.body)

]

public var strongAttributes: TextAttributes?
public var emphasisAttributes: TextAttributes?

public struct HeaderAttributes {
    public var h1Attributes: TextAttributes? = [
        NSFontAttributeName: UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline)
    ]

    public var h2Attributes: TextAttributes? = [
        NSFontAttributeName: UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline)
    ]

    public var h3Attributes: TextAttributes? = [
        NSFontAttributeName: UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline)
    ]

    public var h4Attributes: TextAttributes? = [
        NSFontAttributeName: UIFont.preferredFont(forTextStyle: UIFontTextStyle.subheadline)
    ]

    public var h5Attributes: TextAttributes? = [
        NSFontAttributeName: UIFont.preferredFont(forTextStyle: UIFontTextStyle.subheadline)
    ]

    public var h6Attributes: TextAttributes? = [
        NSFontAttributeName: UIFont.preferredFont(forTextStyle: UIFontTextStyle.subheadline)
    ]

    func attributesForHeaderLevel(_ level: Int) -> TextAttributes? {
        switch level {
        case 1: return h1Attributes
        case 2: return h2Attributes
        case 3: return h3Attributes
        case 4: return h4Attributes
        case 5: return h5Attributes
        case 6: return h6Attributes
        default: return nil
        }
    }

    public init() {}
}

public var headerAttributes: HeaderAttributes? = HeaderAttributes()

fileprivate static let MonospaceFont: UIFont = {
    let bodyFont = UIFont.preferredFont(forTextStyle: UIFontTextStyle.body)
    let size = bodyFont.pointSize
    return UIFont(name: "Menlo", size: size) ?? UIFont(name: "Courier", size: size) ?? bodyFont
}()

public var codeBlockAttributes: TextAttributes? = [
    NSFontAttributeName: MarkdownAttributes.MonospaceFont
]

public var inlineCodeAttributes: TextAttributes? = [
    NSFontAttributeName: MarkdownAttributes.MonospaceFont
]

public var blockQuoteAttributes: TextAttributes? = [
    NSForegroundColorAttributeName: UIColor.darkGray
]

public var orderedListAttributes: TextAttributes? = [
    NSFontAttributeName: fontWithTraits(.traitBold, font: UIFont.preferredFont(forTextStyle: UIFontTextStyle.body))
]

public var orderedListItemAttributes: TextAttributes? = [
    NSFontAttributeName: UIFont.preferredFont(forTextStyle: UIFontTextStyle.body),
    NSForegroundColorAttributeName: UIColor.darkGray
]

public var unorderedListAttributes: TextAttributes? = [
    NSFontAttributeName: fontWithTraits(.traitBold, font: UIFont.preferredFont(forTextStyle: UIFontTextStyle.body))
]

public var unorderedListItemAttributes: TextAttributes? = [
    NSFontAttributeName: UIFont.preferredFont(forTextStyle: UIFontTextStyle.body),
    NSForegroundColorAttributeName: UIColor.darkGray
]

public init() {

}

}

有谁知道我可以如何修复这个错误,所以当调用初始化程序时,值被设置为用户定义的值而不是默认值?

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    在您的代码中,您在使用 MarkdownAttributes() 时使用默认属性显式初始化,您应该将您的 init 方法替换为如下内容:

    public override convenience init() {
        var attributes = MarkdownTextAttributes()
        attributes.strongAttributes = [
            NSForegroundColorAttributeName: UIColor.redColor()
            // Add other attributes here
        ]
        self.init(attributes: attributes)
    }
    

    【讨论】:

      【解决方案2】:

      添加一个获取用户定义值的 init 函数,并调用您的类或超类 init()(取决于您想要做什么......)

      你应该只添加以下函数之一,你不想同时添加它们:

      public override init(attributes: MarkdownAttributes = MarkdownAttributes()) {
         super.init(attributes)
      }
      
      public override convenience init(attributes: MarkdownAttributes = MarkdownAttributes()) {
           init(attributes: attributes)
      }
      

      要调用它,您现在可以使用上面显示的代码:

      let fonty = UIFont(name: font, size: fsize)
      
      attributes.defaultAttributes[NSFontAttributeName] = fonty
      attributes.orderedListAttributes?[NSFontAttributeName] = fonty
      attributes.orderedListItemAttributes?[NSFontAttributeName] = fonty
      attributes.unorderedListAttributes?[NSFontAttributeName] = fonty
      attributes.unorderedListItemAttributes?[NSFontAttributeName] = fonty
      
      let textStorage = MarkdownTextStorage(attributes: attributes)
      

      【讨论】:

      • 您是说要将该函数与已使用的函数一起使用,因为对于您建议的第二个函数的第一行,我收到错误“Initializer does not override a specified initializer from its superclass”。删除覆盖时,我的第二个函数出现以下错误 Invalid redeclaration of 'init(attributes:)'
      • 然后我得到错误 通过此函数的所有路径都将调用自身,当加载行'self.init(attributes:attributes)上的视图时,应用程序在运行时崩溃'
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-09
      • 2016-03-22
      • 1970-01-01
      • 2021-06-02
      相关资源
      最近更新 更多