Very strange problem about "setString" method of NSTextView.

  • Hi,

    I want NSTextView to scroll to one specific position after opened one
    text file (some kind like a bookmark).

    Following is my code:

    [textView setString:contentString];

    NSNumber *scrollerPosition = [bookmarks objectForKey:filePath];
    if (scrollerPosition)
    {
    float maxPosition = NSMaxY([[scrollView documentView] frame]) -
    NSHeight([[scrollView contentView] bounds]);

    if ([scrollerPosition floatValue] < maxPosition)
    {
      NSPoint newPosition = NSMakePoint(0.0, [scrollerPosition floatValue]);

      [[scrollView documentView] scrollPoint:newPosition];
    }
    }

    I found the value of "maxPosition" always be 0.0 when upper code be
    invoked every first time, so I think the "setString" method of
    NSTextView is an async method, the size of scrollView may not be
    changed immediately after "setString" be invoked.

    Then I tried to use

    [textView performSelectorOnMainThread:@selector(setString)
    withObject:contentString waitUntilDone:YES]

    instead of

    [textView setString:contentString]

    But it still won't work..... What should I do now?

    Allen Dang
    <allengnr...>
  • On Dec 30, 2007, at 4:31 AM, Allen Dang wrote:

    > Then I tried to use
    >
    > [textView performSelectorOnMainThread:@selector(setString)
    > withObject:contentString waitUntilDone:YES]
    >
    > instead of
    >
    > [textView setString:contentString]
    >
    > But it still won't work..... What should I do now?

    That wouldn't work like you expect. Try something like this instead:

    - (void) mySetString:(NSString *) contentString
    {
    [textView setString: contentString];
    [self performSelector: @selector(updateBookmark) withObject: nil
    afterDelay: 0.0];
    }

    - (void) updateBookmark
    {
    // The code that sets the bookmark
    }

    j o a r
  • On 30 Dec 2007, at 19:55, j o a r wrote:

    >
    > On Dec 30, 2007, at 4:31 AM, Allen Dang wrote:
    >
    >> Then I tried to use
    >>
    >> [textView performSelectorOnMainThread:@selector(setString)
    >> withObject:contentString waitUntilDone:YES]
    >>
    >> instead of
    >>
    >> [textView setString:contentString]
    >>
    >> But it still won't work..... What should I do now?
    >

    That should work as far as I can see, but you've got the selector
    wrong. It's:

    >> [textView performSelectorOnMainThread:@selector(setString:)
    >> withObject:contentString waitUntilDone:YES]
  • On Dec 30, 2007, at 12:20 PM, Mike Abdullah wrote:

    > That should work as far as I can see, but you've got the selector
    > wrong. It's:
    >
    >>> [textView performSelectorOnMainThread:@selector(setString:)
    >>> withObject:contentString waitUntilDone:YES]

    It still doesn't work - And even if it did, I wouldn't recommend it as
    it's not intention revealing, and (IMO) would rely to much on the
    particular implementation of "-
    performSelectorOnMainThread:withObject:waitUntilDone:".

    If you're already on the main thread, I think that this call:

    [obj performSelectorOnMainThread: @selector(foo) withObject: nil
    waitUntilDone: YES];

    ...should *conceptually* be viewed as the same as this call:

    [obj foo];

    If, like in this case, you want to do something after the current run
    loop, and on the same thread, you should use a regular "-
    performSelector:withObject:afterDelay:".

    j o a r
previous month december 2007 next month
MTWTFSS
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
Go to today