简体   繁体   English

NSTextStorage的备用后备存储

[英]Alternate backing store for NSTextStorage

Every example shows an NSMutableAttributedString as the "backing store" for keeping the text and attributes related to viewing/editing text. 每个示例均显示NSMutableAttributedString作为“后备存储”,用于保留文本和与查看/编辑文本相关的属性。 How can I use an alternate, such as std::string or maybe content from a database. 如何使用替代项,例如std :: string或数据库中的内容。 Just as a test, I have created a subclass and hardcoded it to return default values when I overrode the required methods. 就像测试一样,我创建了一个子类并对其进行硬编码,以便在覆盖所需方法时返回默认值。 However, when I run it on an iPhone 5 device, it just shows a black screen, until I hit the Home button. 但是,当我在iPhone 5设备上运行它时,它只会显示黑屏,直到我按下“主页”按钮。 The system continuously calls attributesAtIndex:location:effectiveRange: range: and the CPU usage level goes up to 100% and the App never does anything. 系统连续调用attributeAtIndex:location:effectiveRange:range:并且CPU使用率达到100%,并且该应用程序从不执行任何操作。 It does call the string: method once, but then just keeps calling the attributesAtIndex:location:effectiveRange:range 它确实调用过string:方法一次,但是随后继续调用attributeAtIndex:location:effectiveRange:range

The example: 这个例子:

@implementation MyTextStorage
{
}

- (id)init
{
    self = [super init];

    if (self)
    {
    }

    return self;
}


#pragma mark - Reading Text

- (NSString *)string
{
    return @"Static"; 
}

- (NSDictionary *)attributesAtIndex:(NSUInteger)location effectiveRange:(NSRangePointer)range
{
    return  @{NSFontAttributeName:  [UIFont fontWithName:@"Noteworthy-Bold" size:36] } ;
}

#pragma mark - Text Editing

- (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str
{
    // Empty - Don't allow editing
}

- (void)setAttributes:(NSDictionary *)attrs range:(NSRange)range
{
    // Empty - Don't allow editing
}

- (void)processEditing
{
    [super processEditing];
}




@end

And here is how it is being setup: 这是它的设置方式:

    // property
    self.textStorage = [MyTextStorage new];

    // Create layout manager, and attach text storage to layout manager.
    NSLayoutManager* layoutManager = [[NSLayoutManager alloc] init];
    [self.textStorage addLayoutManager: layoutManager];

    // Create text container and attach to layout manager
    CGSize size = self.view.bounds.size;
    size.height = size.height/2;

    NSTextContainer* textContainer = [[NSTextContainer alloc] initWithSize: size];
    [layoutManager addTextContainer: textContainer];

    // Create text view, given text container.
    CGRect frame1 = CGRectMake(0, 20, size.width, size.height);
    UITextView *tv1 = [[UITextView alloc] initWithFrame:frame1 textContainer: textContainer];
    [self.view addSubview: tv1];

I understand NSTextStorage is a Class Cluster, which seems to mean that it is an abstract class factory. 我了解NSTextStorage是一个类集群,这似乎意味着它是一个抽象类工厂。 I really don't understand why I can't use another "backing store". 我真的不明白为什么我不能使用另一个“后备店”。 My plan was to use a std::string (because of reasons of where my data is coming from) and then return a constant attribute style (like in the above code). 我的计划是使用std :: string(由于数据来自何处的原因),然后返回常量属性样式(如上述代码)。 I've been reading everything I can about NSTextStorage, NSLayoutManager, NSTextContainer and NSTextView, including mac OS X documents (even though I'm doing this on iOS). 我一直在阅读有关NSTextStorage,NSLayoutManager,NSTextContainer和NSTextView的所有资料,包括mac OS X文档(即使我在iOS上也是如此)。 Thanks! 谢谢!

NSRangePointer is basically a pointer to NSRange . NSRangePointer基本上是指向NSRange的指针。 You will need to set it before exit the method if it is not null. 如果不为null,则需要在退出方法之前进行设置。 Like this: 像这样:

- (NSDictionary *)attributesAtIndex:(NSUInteger)location effectiveRange:(NSRangePointer)range {
    if(range != NULL){
        range->location = 0;
        range->length = self.string.length;
    }
    return  @{NSFontAttributeName:  [UIFont fontWithName:@"Noteworthy-Bold" size:36] } ;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM