Określić, czy UIView jest widoczny dla użytkownika?

Czy jest możliwe ustalenie, czy moje {[0] } jest widoczne dla użytkownika, czy nie?

Mój widok jest dodawany jako subview kilka razy do Tab Bar Controller.

Każda instancja tego widoku ma NSTimer, która aktualizuje widok.

Nie chcę jednak aktualizować widoku, który nie jest widoczny dla użytkownika.

Czy to możliwe?

Dzięki

Author: Undo, 2009-10-08

8 answers

Możesz sprawdzić, czy:

  • jest ukryty, sprawdzając widok.hidden
  • znajduje się w hierarchii widoku, sprawdzając view.superview != nil
  • Możesz sprawdzić granice widoku, aby sprawdzić, czy jest on na ekranie
Jedyną rzeczą, o której mogę myśleć, jest to, że twój pogląd jest ukryty za innymi i nie może być widziany z tego powodu. Być może będziesz musiał przejść przez wszystkie widoki, które przychodzą po, aby zobaczyć, czy zaciemniają one twój widok.
 70
Author: mahboudz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-07 23:58:29

Dla każdego, kto tu skończy:

Aby określić, czy UIView jest gdzieś na ekranie, zamiast sprawdzać superview != nil, lepiej sprawdzić, czy window != nil. W pierwszym przypadku możliwe jest, że Widok ma superview, ale nie ma go na ekranie:

if (view.window != nil) {
    // do stuff
}

Oczywiście należy również sprawdzić, czy jest to hidden lub czy ma alpha > 0.

Jeśli nie chcesz, aby twój NSTimer działał, gdy widok nie jest widoczny, powinieneś ręcznie ukryć te widoki, jeśli to możliwe i zatrzymać czasomierz, gdy widok jest ukryty. Jednak nie jestem pewien, co robisz.

 86
Author: walkingbrad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-12 21:26:42

To określi, czy ramka widoku mieści się w granicach wszystkich jego superwizji (aż do widoku głównego). Jednym z praktycznych przypadków użycia jest określenie, czy Widok potomny jest (przynajmniej częściowo) widoczny w widoku przewijania.

func isVisible(view: UIView) -> Bool {
    func isVisible(view: UIView, inView: UIView?) -> Bool {
        guard let inView = inView else { return true }
        let viewFrame = inView.convertRect(view.bounds, fromView: view)
        if CGRectIntersectsRect(viewFrame, inView.bounds) {
            return isVisible(view, inView: inView.superview)
        }
        return false
    }
    return isVisible(view, inView: view.superview)
}

Potencjalne ulepszenia:

  • Respect alpha i hidden.
  • [[9]}Respect clipsToBounds, ponieważ Widok może przekroczyć granice jego superwizji, jeśli jest fałszywy.
 16
Author: John Gibb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-06 20:15:21

Rozwiązaniem, które zadziałało dla mnie, było najpierw sprawdzenie, czy Widok ma okno, a następnie iteracja nad podglądem i sprawdzenie, czy:

  1. widok nie jest ukryty.
  2. widok mieści się w granicach superwizji.
Wygląda na to, że jak na razie działa dobrze.

Swift 3.0

public func isVisible(view: UIView) -> Bool {

  if view.window == nil {
    return false
  }

  var currentView: UIView = view
  while let superview = currentView.superview {

    if (superview.bounds).intersects(currentView.frame) == false {
      return false;
    }

    if currentView.isHidden {
      return false
    }

    currentView = superview
  }

  return true
}
 8
Author: AlexGordon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-14 13:06:23

Naprawdę chcesz wiedzieć, czy widok jest widoczny dla użytkownika, musisz wziąć pod uwagę następujące elementy:

  • jest oknem widoku nie zerowym i jest równe najlepszemu oknu
  • jest widokiem, a wszystkie jego superviews alpha > = 0.01 (wartość progowa używana również przez UIKit do określenia, czy powinien obsługiwać dotknięcia) i nie jest ukryta
  • jest indeksem z (wartością stosu) widoku wyższym niż inne widoki w tej samej hierarchii.
  • nawet jeśli indeks z jest niższy, może być widoczny, jeśli inne widoki na górze mają przezroczysty kolor tła, alpha 0 lub są ukryte.

Szczególnie przezroczysty kolor tła widoków z przodu może stanowić problem do sprawdzenia programowo. Jedynym sposobem, aby być naprawdę pewnym, jest wykonanie programowej migawki widoku, aby sprawdzić i odróżnić ją w ramce z migawką całego ekranu. Nie będzie to jednak działać w przypadku widoków, które nie są wystarczająco charakterystyczne (np. w pełni białe).

Dla inspiracji zobacz metoda jest viewvisible w projekcie iOS-server

 3
Author: Werner Altewischer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-07 12:52:57

W viewWillAppear ustaw wartość" isVisible " na true, w viewWillDisappear ustaw ją na false. Najlepszym sposobem, aby wiedzieć o UITabBarController podviews, działa również dla kontrolerów nawigacji.

 2
Author: BadPirate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-26 18:34:15

To pomoże Ci dowiedzieć się, czy Twój UIView jest najbardziej widocznym widokiem. Może być pomocny:

let visibleBool = view.superview?.subviews.last?.isEqual(view)
//have to check first whether it's nil (bc it's an optional) 
//as well as the true/false 
if let visibleBool = visibleBool where visibleBool { value
  //can be seen on top
} else {
  //maybe can be seen but not the topmost view
}
 1
Author: teradyl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-26 20:53:39

Jeśli używasz ukrytej właściwości view, to:

Widok.ukryty (cel C) lub widok.isHidden (swift) jest właściwością do odczytu/zapisu. Więc możesz łatwo czytać lub pisać

Dla swift 3.0

if(view.isHidden){
   print("Hidden")
}else{
   print("visible")
}
 0
Author: Deepak Chaudhary,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-08 12:17:11