UIView를 강제로 다시 그리는 가장 강력한 방법은 무엇입니까?
항목 목록이있는 UITableView가 있습니다. 항목을 선택하면 viewController가 푸시되고 다음이 진행됩니다. viewDidLoad 메서드에서 내 하위보기에 필요한 데이터에 대해 URLRequest를 해제합니다. drawRect가 재정의 된 UIView 하위 클래스입니다. 데이터가 클라우드에서 도착하면 뷰 계층을 구축하기 시작합니다. 문제의 서브 클래스는 데이터를 전달받으며 drawRect 메소드는 이제 렌더링에 필요한 모든 것을 갖습니다.
그러나.
drawRect를 명시 적으로 호출하지 않기 때문에-Cocoa-Touch에서 처리합니다.-Cocoa-Touch에 실제로이 UIView 서브 클래스가 렌더링되기를 원한다고 알려주는 방법이 없습니다. 언제? 이제 좋을 것입니다!
[myView setNeedsDisplay]를 사용해 보았습니다. 이것은 때때로 작동합니다. 매우 드문 드문
나는 몇 시간 동안 이것과 씨름하고 있습니다. UIView를 다시 렌더링하도록 강력하고 확실한 접근 방식을 제공해 주시겠습니까?
다음은 뷰에 데이터를 공급하는 코드 스 니펫입니다.
// Create the subview
self.chromosomeBlockView = [[[ChromosomeBlockView alloc] initWithFrame:frame] autorelease];
// Set some properties
self.chromosomeBlockView.sequenceString = self.sequenceString;
self.chromosomeBlockView.nucleotideBases = self.nucleotideLettersDictionary;
// Insert the view in the view hierarchy
[self.containerView addSubview:self.chromosomeBlockView];
[self.containerView bringSubviewToFront:self.chromosomeBlockView];
// A vain attempt to convince Cocoa-Touch that this view is worthy of being displayed ;-)
[self.chromosomeBlockView setNeedsDisplay];
건배, 더그
UIView
를 다시 렌더링 하도록 보장하는 확실한 방법 입니다 [myView setNeedsDisplay]
. 문제가있는 경우 다음 문제 중 하나에 해당 될 수 있습니다.
실제로 데이터를 갖기 전에 호출하거나
-drawRect:
무언가를 캐싱하고 있습니다.이 메소드를 호출하는 순간 뷰가 그려 질 것으로 예상됩니다. Cocoa 그리기 시스템을 사용하여 "지금 당장 두 번째 그리기"를 요구할 방법이 없습니다. 그것은 전체보기 합성 시스템, 쓰레기 성능을 방해하고 모든 종류의 인공물을 만들 것입니다. "다음 드로우 사이클에서 드로우해야합니다"라고 말하는 방법 만 있습니다.
당신이 필요로하는 것이 "일부 로직, 그리기, 더 많은 로직"이라면, "일부 더 많은 로직"을 별도의 메소드에 -performSelector:withObject:afterDelay:
넣고 0의 지연을 사용하여 호출해야합니다. 다음 추첨주기. 이러한 종류의 코드 예제와 필요할 수있는 경우에 대해서는 이 질문 을 참조하십시오 (가능한 경우 코드를 복잡하게하기 때문에 다른 솔루션을 찾는 것이 가장 좋습니다).
물건이 그려지지 않는다고 생각되면 중단 점을 넣고 -drawRect:
언제 전화를했는지 확인하십시오. 을 호출 -setNeedsDisplay
하지만 -drawRect:
다음 이벤트 루프에서 호출되지 않으면 뷰 계층 구조를 파헤쳐 서 현명하지 않도록하십시오. 지나치게 영리하다는 것은 내 경험에서 잘못된 그림을 그리는 가장 큰 원인입니다. 시스템이 원하는 것을 수행하도록 속이는 방법을 가장 잘 알고 있다고 생각하면 일반적으로 원하지 않는 것을 정확하게 수행하게됩니다.
setNeedsDisplay와 drawRect : (5 초) 호출 사이에 큰 지연 문제가있었습니다. 메인 스레드와 다른 스레드에서 setNeedsDisplay를 호출했습니다. 이 호출을 메인 스레드로 옮긴 후 지연이 사라졌습니다.
이것이 도움이되기를 바랍니다.
(호출 코드로 돌아 가기 전에) 동기식 으로 뷰를 강제로 작성하는 환불 보장, 강화 된 확실한 방법 은 하위 클래스 와의 상호 작용 을 구성하는 것 입니다.CALayer
UIView
당신의 UIView의 하위 클래스에서는 생성 - display
"고 레이어 알 방법 예는 디스플레이를 필요를 "다음 " 그래서 만들려면 "
/// Redraws the view's contents immediately.
/// Serves the same purpose as the display method in GLKView.
/// Not to be confused with CALayer's `- display`; naming's really up to you.
- (void)display
{
CALayer *layer = self.layer;
[layer setNeedsDisplay];
[layer displayIfNeeded];
}
또한 - drawLayer:inContext:
개인 / 내부 그리기 메서드를 호출 하는 메서드를 구현합니다 (모든 UIView가 CALayerDelegate이므로 작동합니다) .
/// Called by our CALayer when it wants us to draw
/// (in compliance with the CALayerDelegate protocol).
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context
{
UIGraphicsPushContext(context);
[self internalDrawWithRect:self.bounds];
UIGraphicsPopContext();
}
그리고 - internalDrawWithRect:
안전 장치와 함께 사용자 정의 방법을 만드십시오 - drawRect:
.
/// Internal drawing method; naming's up to you.
- (void)internalDrawWithRect:(CGRect)rect
{
// @FILLIN: Custom drawing code goes here.
// (Use `UIGraphicsGetCurrentContext()` where necessary.)
}
/// For compatibility, if something besides our display method asks for draw.
- (void)drawRect:(CGRect)rect {
[self internalDrawWithRect:rect];
}
And now just call [myView display]
whenever you really-really need it to draw. - display
will tell the CALayer
to displayIfNeeded
, which will synchronously call back into our - drawLayer:inContext:
and do the drawing in - internalDrawWithRect:
, updating the visual with what's drawn into the context before moving on.
This approach is similar to @RobNapier's above, but has the advantage of calling - displayIfNeeded
in addition to - setNeedsDisplay
, which makes it synchronous.
This is possible because CALayer
s expose more drawing functionality than UIView
s do— layers are lower-level than views and designed explicitly for the purpose of highly-configurable drawing within the layout, and (like many things in Cocoa) are designed to be used flexibly (as a parent class, or as a delegator, or as a bridge to other drawing systems, or just on their own).
More information about the configurability of CALayer
s can be found in the Setting Up Layer Objects section of the Core Animation Programming Guide.
I had the same problem, and all the solutions from SO or Google didn't work for me. Usually, setNeedsDisplay
does work, but when it doesn't...
I've tried calling setNeedsDisplay
of the view just every possible way from every possible threads and stuff - still no success. We know, as Rob said, that
"this needs to be drawn in the next draw cycle."
But for some reason it wouldn't draw this time. And the only solution I've found is calling it manually after some time, to let anything that blocks the draw pass away, like this:
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW,
(int64_t)(0.005 * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
[viewToRefresh setNeedsDisplay];
});
It's a good solution if you don't need the view to redraw really often. Otherwise, if you're doing some moving (action) stuff, there is usually no problems with just calling setNeedsDisplay
.
I hope it will help someone who is lost there, like I was.
Well I know this might be a big change or even not suitable for your project, but did you consider not performing the push until you already have the data? That way you only need to draw the view once and the user experience will also be better - the push will move in already loaded.
The way you do this is in the UITableView
didSelectRowAtIndexPath
you asynchronously ask for the data. Once you receive the response, you manually perform the segue and pass the data to your viewController in prepareForSegue
. Meanwhile you may want to show some activity indicator, for simple loading indicator check https://github.com/jdg/MBProgressHUD
참고URL : https://stackoverflow.com/questions/1503761/what-is-the-most-robust-way-to-force-a-uiview-to-redraw
'program story' 카테고리의 다른 글
C #에서 개체 속성 비교 (0) | 2020.07.28 |
---|---|
MySQL-하나의 쿼리에서 다른 값으로 여러 행 업데이트 (0) | 2020.07.28 |
새로운 대기열에 자동으로 기존 값을 대기열에 넣는 고정 크기 대기열 (0) | 2020.07.28 |
Javascript에서 일부 비동기 작업이 완료되기를 기다리는 가장 간단한 방법은 무엇입니까? (0) | 2020.07.28 |
이상한 SQLAlchemy 오류 메시지 : TypeError : 'dict'개체가 인덱싱을 지원하지 않습니다 (0) | 2020.07.28 |