Pytanie Jak programowo umieścić wskaźnik aktywności w centrum jego superwizji za pomocą automatycznego układania?


Dlaczego poniższy kod nie działa dla wskaźnika aktywności pozycjonowania w centrum jego superview:

UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc]
       initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];

[self.mysuperview addSubview:activityIndicator];
[activityIndicator addConstraints:[NSLayoutConstraint 
                   constraintsWithVisualFormat:@"|-(>=20)-[view(==100)]-(>=20)-|"
                   options:NSLayoutFormatAlignAllCenterX | NSLayoutFormatAlignAllCenterY
                   metrics:nil
                   views:@{@"view" : self.mysuperview}]];

Wskaźnik aktywności znajduje się gdzieś w lewym górnym rogu, zdecydowanie nie w środku.

================== Aktualizacja: ZNALEZIONO ROZWIĄZANIE: Muszę wyłączyć ograniczenia autorezjowania po stworzeniu wskaźnika, a następnie wszystkie rozwiązania, w których dana praca:

 [activityIndicator setTranslatesAutoresizingMaskIntoConstraints:NO];

Znalazłem go na linku podanym przez @Vignesh, więc akceptuję jego / jej odpowiedź.


18
2017-10-17 15:43


pochodzenie


Informacje, jeśli używasz github.com/dkduck/FLKAutoLayout to też jest dla ciebie. - tarmes
wolę github.com/Masonry/Masonry - user1007522
Tak. To było również translateAutoresizingMaskIntoConstraints dla mnie. Łatwo zapomnieć. - John Erck
OMG Miałem ten sam błąd. - coolcool1994
Widzieć moja odpowiedź daje to 4 różne sposoby rozwiązania problemu za pomocą automatycznego układu lub sprężyny i rozpórki. - Imanou Petit


Odpowiedzi:


Możesz spróbować tego,

 UIView *superview = self.mysuperview;
NSDictionary *variables = NSDictionaryOfVariableBindings(activityIndicator, superview);
NSArray *constraints =
[NSLayoutConstraint constraintsWithVisualFormat:@"V:[superview]-(<=1)-[activityIndicator]"
                                        options: NSLayoutFormatAlignAllCenterX
                                        metrics:nil
                                          views:variables];
[self.view addConstraints:constraints];

constraints =
[NSLayoutConstraint constraintsWithVisualFormat:@"H:[superview]-(<=1)-[activityIndicator]"
                                        options: NSLayoutFormatAlignAllCenterY
                                        metrics:nil
                                          views:variables];
[self.view addConstraints:constraints];

Pochodzi z tutaj.


2
2017-10-17 15:52



dzięki za link, pomógł mi znaleźć odpowiedź. Rozwiązaniem jest [activityIndicator setTranslatesAutoresizingMaskIntoConstraints: NO]; - zyxel


Cztery następujące próbki kodu Swift 3 pokazują, jak wyśrodkować a UIActivityIndicatorView w środku UIView z UIViewController z Automatyczny układ.

Wszystkie próbki dają taki sam wynik, ale zgodnie z twoimi potrzebami i gustami możesz wybrać jedną lub drugą.

Jeżeli twój UIActivityIndicatorViewSuperview nie jest self.view, musisz po prostu wymienić każdą self.view zadzwoń z własnym (nieopakowane) superview.


1. NSLayoutConstraint styl

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let indicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray)
        indicatorView.isHidden = false
        indicatorView.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(indicatorView)

        // Auto layout
        let horizontalConstraint = NSLayoutConstraint(item: indicatorView,
                                                      attribute: .centerX,
                                                      relatedBy: .equal,
                                                      toItem: self.view,
                                                      attribute: .centerX,
                                                      multiplier: 1,
                                                      constant: 0)
        let verticalConstraint = NSLayoutConstraint(item: indicatorView,
                                                    attribute: .centerY,
                                                    relatedBy: .equal,
                                                    toItem: self.view,
                                                    attribute: .centerY,
                                                    multiplier: 1,
                                                    constant: 0)
        NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])
        /*
         // You can replace NSLayoutConstraint activate(_:) call with the following lines:
         self.view.addConstraint(horizontalConstraint)
         self.view.addConstraint(verticalConstraint)
         */
    }

}

2. UIViewAutoresizing styl

Sprężyny i rozpórki zostaną przetłumaczone na odpowiednie ograniczenia układu automatycznego w czasie wykonywania.

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let indicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray)
        indicatorView.isHidden = false
        indicatorView.translatesAutoresizingMaskIntoConstraints = true // default is true
        self.view.addSubview(indicatorView)

        // Springs and struts
        indicatorView.center = CGPoint(x: self.view.bounds.midX, y: self.view.bounds.midY)
        indicatorView.autoresizingMask = [
            .flexibleLeftMargin,
            .flexibleRightMargin,
            .flexibleTopMargin,
            .flexibleBottomMargin
        ]
    }

}

3. Styl języka Visual Format

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let indicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray)
        indicatorView.isHidden = false
        indicatorView.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(indicatorView)

        // Auto layout
        let views: [String: Any] = ["superview": self.view, "indicatorView": indicatorView]
        let horizontalConstraints = NSLayoutConstraint
            .constraints(withVisualFormat: "H:[superview]-(<=0)-[indicatorView]",
                         options: .alignAllCenterY,
                         metrics: nil,
                         views: views)
        let verticalConstraints = NSLayoutConstraint
            .constraints(withVisualFormat: "V:[superview]-(<=0)-[indicatorView]",
                         options: .alignAllCenterX,
                         metrics: nil,
                         views: views)
        self.view.addConstraints(horizontalConstraints)
        self.view.addConstraints(verticalConstraints)
    }

}

4. NSLayoutAnchor styl (wymaga iOS 9)

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let indicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray)
        indicatorView.isHidden = false
        indicatorView.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(indicatorView)

        // Auto layout
        let horizontalConstraint = indicatorView
            .centerXAnchor.constraint(equalTo: self.view.centerXAnchor)
        let verticalConstraint = indicatorView
            .centerYAnchor.constraint(equalTo: self.view.centerYAnchor)
        NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])
        /*
         // You can replace NSLayoutConstraint activate(_:) call with the following lines:
         self.view.addConstraint(horizontalConstraint)
         self.view.addConstraint(verticalConstraint)
         */
    }

}

16
2018-01-05 21:56



Styl wizualny języka formatu pracował dla mnie! Dzięki @Imanou Petit - Nii Mantse


Spełnia on swoje wymagania, będąc w kącie, ponieważ nie twierdzisz, że luki z każdej strony muszą być takie same. Spróbuj zamiast tego:

[self.superview addConstraint:[NSLayoutConstraint constraintWithItem:activityIndicator
               attribute:NSLayoutAttributeCenterX 
               relatedBy:NSLayoutRelationEqual 
                  toItem:self.superview 
               attribute:NSLayoutAttributeCenterX 
              multiplier:1.0 
                constant:0.0]];

Aby wyśrodkować w pionie, wykonaj następujące czynności:

[self.superview addConstraint:[NSLayoutConstraint constraintWithItem:activityIndicator
               attribute:NSLayoutAttributeCenterY 
               relatedBy:NSLayoutRelationEqual 
                  toItem:self.superview 
               attribute:NSLayoutAttributeCenterY 
              multiplier:1.0 
                constant:0.0]];

Alternatywnie, bardzo polecam użycie projektu FLKAutoLayout, aby uprościć to wszystko:

https://github.com/dkduck/FLKAutoLayout

Następnie możesz zrobić:

[activityIndicator alignCenterXWithView:self.superview predicate:nil];
[activityIndicator alignCenterYWithView:self.superview predicate:nil];

Co jest miłe :)


6
2017-10-17 15:49



Musisz dodać CenterY także jeśli chcesz, aby znajdował się w centrum. Tylko X może znajdować się w dowolnym miejscu na linii pionowej pośrodku superwizora. - Fogmeister
Tak, ale kod plakatu próbował tylko wycentrować, więc zakładam, że taki był wymóg ... Niemniej jednak zaktualizuję ... - tarmes
Ach, przepraszam, nie zdawałem sobie z tego sprawy. - Fogmeister
Muszę faktycznie wyśrodkować zarówno poziomo, jak i pionowo. Nie wiem, co robię źle, ale w jakiś sposób to rozwiązanie również nie działa. - zyxel
Sprawdź, czy mają wspólny super widok. - tarmes


Wyśrodkowałem wskaźnik aktywności w jego widoku nadrzędnym, dodając go w Konstruktorze interfejsów z wartością alfa zero (i IBOutlet dla niego w mojej klasie kontrolera widoku). Następnie dodałem wiązania, aby wyśrodkować je w osiach X i Y. Na koniec dodałem do niego ograniczenia szerokości i wysokości, aby wyciszyć błąd autouzupełniania.

Według mojej metody kontrolera startActivityIndicator ustawiłem alfa wskaźnika aktywności na jeden i wywołuję na nim metodę startAnimating. W metodzie stopActivityIndicator wywołuję metodę stopAnimating i ustawię wskaźnik alfa wskaźnika aktywności na zero.


0
2017-11-02 00:30