programing

앱이 백그라운드에서 돌아왔을 때 viewApp이 호출되지 않는 이유는 무엇입니까?

css3 2023. 4. 15. 09:11

앱이 백그라운드에서 돌아왔을 때 viewApp이 호출되지 않는 이유는 무엇입니까?

앱 작성 중인데 사용자가 통화 중 앱을 보고 있다면 뷰를 변경해야 합니다.

다음 방법을 구현했습니다.

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    NSLog(@"viewWillAppear:");
    _sv.frame = CGRectMake(0.0, 0.0, 320.0, self.view.bounds.size.height);
}

그러나 앱이 포그라운드로 돌아왔을 때 호출되지 않습니다.

다음 기능을 구현할 수 있습니다.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarFrameChanged:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil];

하지만 난 이걸 하고 싶지 않아.모든 레이아웃 정보를 viewWillAple: 메서드에 저장하고 가능한 모든 시나리오를 처리하도록 하겠습니다.

applicationWillEnterForground:에서 viewWillAple:로 전화를 걸어봤지만 현재 뷰 컨트롤러가 무엇인지 정확히 알 수 없습니다.

이 일을 어떻게 처리해야 할지 아는 사람 있나요?내가 확실한 해결책을 놓치고 있는 게 확실해.

재빠르다

단답

를 사용하다NotificationCenter보다 관찰자viewWillAppear.

override func viewDidLoad() {
    super.viewDidLoad()

    // set observer for UIApplication.willEnterForegroundNotification
    NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)

}

// my selector that was defined above
@objc func willEnterForeground() {
    // do stuff
}

장답

앱이 백그라운드에서 돌아오는 시기를 확인하려면NotificationCenter보다 관찰자viewWillAppear다음은 어떤 이벤트가 언제 발생하는지 보여주는 샘플 프로젝트입니다.(이것은 이 Objective-C 답변을 개작한 것입니다.)

import UIKit
class ViewController: UIViewController {

    // MARK: - Overrides

    override func viewDidLoad() {
        super.viewDidLoad()
        print("view did load")

        // add notification observers
        NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)

    }

    override func viewWillAppear(_ animated: Bool) {
        print("view will appear")
    }

    override func viewDidAppear(_ animated: Bool) {
        print("view did appear")
    }

    // MARK: - Notification oberserver methods

    @objc func didBecomeActive() {
        print("did become active")
    }

    @objc func willEnterForeground() {
        print("will enter foreground")
    }

}

앱을 처음 시작할 때 출력 순서는 다음과 같습니다.

view did load
view will appear
did become active
view did appear

홈 버튼을 누른 후 앱을 다시 맨 앞으로 가져오면 출력 순서는 다음과 같습니다.

will enter foreground
did become active 

그래서 만약 당신이 원래 이 장치를 사용하려 했다면viewWillAppear그리고나서UIApplication.willEnterForegroundNotification아마 당신이 원하는 걸 거예요

메모

iOS 9 이후에는 옵서버를 제거할 필요가 없습니다.문서에는 다음과 같이 기술되어 있습니다.

앱이 iOS 9.0 이후 또는 MacOS 10.11 이후를 대상으로 하는 경우 앱에서 옵서버의 등록을 취소할 필요가 없습니다.dealloc방법.

방법viewWillAppear다른 앱에서 어플리케이션으로 다시 전환할 때 어플리케이션이 전면에 배치되는 상황이 아니라 자신의 어플리케이션에서 일어나고 있는 상황으로 촬영해야 합니다.

즉, 누군가가 다른 어플리케이션을 보거나 전화를 걸었을 때 백그라운드에 있던 어플리케이션으로 다시 전환한 경우, 앱을 떠났을 때 이미 표시되었던 UIViewController는 말하자면, 앱은 사라지지 않고 아직 표시된다.viewWillAppear호출되지 않습니다.

전화하지 말 것을 권장합니다.viewWillAppear자기 자신 --그것은 당신이 전복시켜서는 안 되는 특별한 의미를 가지고 있다!동일한 효과를 얻기 위해 수행할 수 있는 리팩터링은 다음과 같습니다.

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self doMyLayoutStuff:self];
}

- (void)doMyLayoutStuff:(id)sender {
    // stuff
}

후, 「」도 트리거 합니다.doMyLayoutStuff적절한 통지로부터, 다음의 정보를 참조해 주세요.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doMyLayoutStuff:) name:UIApplicationDidChangeStatusBarFrameNotification object:self];

참고로 어떤 것이 '최신' UIView Controller인지 바로 알 수 있는 방법은 없습니다.단, UINavigationController에는 UIViewController가 언제 표시되는지 알아내는 위임 방법이 있습니다.이러한 기능을 사용하여 제시된 최신 UIView Controller를 추적할 수 있습니다.

갱신하다

다양한 비트에 적절한 자동 크기 조정 마스크를 사용하여 UI를 레이아웃하면 UI에 배치되어 있는 '수동'을 처리할 필요도 없습니다.그냥 처리됩니다.

[ Notification Center ]의 [ 를 사용합니다.viewDidLoad: Controller의 하고 거기에서 Controller에서 할 합니다.viewWillAppear:★★★★★★★★★★★★★★★★★★★」viewWillAppear:직접 사용하는 것은 좋지 않습니다.

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"view did load");

    [[NSNotificationCenter defaultCenter] addObserver:self 
        selector:@selector(applicationIsActive:) 
        name:UIApplicationDidBecomeActiveNotification 
        object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self 
        selector:@selector(applicationEnteredForeground:) 
        name:UIApplicationWillEnterForegroundNotification
        object:nil];
}

- (void)applicationIsActive:(NSNotification *)notification {
    NSLog(@"Application Did Become Active");
}

- (void)applicationEnteredForeground:(NSNotification *)notification {
    NSLog(@"Application Entered Foreground");
}

viewWillAppear:animated:제 생각에 iOS SDK에서 가장 혼란스러운 방법 중 하나인 이 경우 응용 프로그램 전환과 같은 상황에서는 호출되지 않습니다.이 메서드는 뷰 컨트롤러의 뷰와 애플리케이션 창의 관계에 따라 호출됩니다.즉, 뷰 컨트롤러의 뷰가 화면이 아닌 애플리케이션 창에 표시되는 경우에만 메시지가 뷰 컨트롤러로 전송됩니다.

응용 프로그램이 백그라운드로 이동하면 응용 프로그램 창의 맨 위 보기가 사용자에게 더 이상 표시되지 않습니다.그러나 응용 프로그램 창의 관점에서는 이러한 보기가 여전히 최상위 보기이므로 창에서 사라지지 않습니다.오히려 애플리케이션 창이 사라졌기 때문에 이러한 뷰는 사라졌습니다.그들은 창문에서 사라졌기 때문에 사라지지 않았다.

따라서 사용자가 다시 응용 프로그램으로 전환하면 창이 다시 나타나기 때문에 화면에 나타나는 것처럼 보입니다. 뷰컨트롤러하지 않습니다.viewWillAppear:animated★★★★★★★★★★★★★★★★★★.

Swift 4.2 / 5

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground),
                                           name: Notification.Name.UIApplication.willEnterForegroundNotification,
                                           object: nil)
}

@objc func willEnterForeground() {
   // do what's needed
}

가능한 한 간단하게 하기 위해서입니다.아래의 코드를 참조하십시오.

- (void)viewDidLoad
{
   [self appWillEnterForeground]; //register For Application Will enterForeground
}


- (id)appWillEnterForeground{ //Application will enter foreground.

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(allFunctions)
                                                 name:UIApplicationWillEnterForegroundNotification
                                               object:nil];
    return self;
}


-(void) allFunctions{ //call any functions that need to be run when application will enter foreground 
    NSLog(@"calling all functions...application just came back from foreground");


}

Swift를 사용하면 더욱 쉬워집니다.UI:

var body: some View {     
    Text("Hello World")
    .onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
        print("Moving to background!")
    }
    .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
        print("Moving back to foreground!")
    }   
}

언급URL : https://stackoverflow.com/questions/5277940/why-does-viewwillappear-not-get-called-when-an-app-comes-back-from-the-backgroun