簡體   English   中英

視圖已添加到UIViewControllerWrapperView,但顯示不正確

[英]View is added to UIViewControllerWrapperView, but it doesn't appear correctly

我試圖在UITableViewController頂部顯示加載指示器。 因此,我將子視圖添加到myTableViewontroller.View.Superview ,即UIViewControllerWrapperView 到目前為止,此方法仍然有效,但並非在所有情況下都有效。 如果將UITableViewController第一次添加到導航堆棧中,則可以根據需要頻繁顯示加載指示器。 如果我彈出UITableViewController並將其新實例再次推入導航堆棧,則不會顯示加載指示器。 連續的通話使加載指示再次出現!

我試圖在UpdateConstraintsLayoutSubviews設置約束,但並沒有幫助。 不知何故,框架的高度似乎為零。 檢查框架顯示以下內容:

正常情況:

parent:{X=0,Y=0,Width=320,Height=480}
hud:{X=0,Y=0,Width=0,Height=0}
parent - before setting up constraints{X=0,Y=0,Width=320,Height=480}
hud - after hud showing: {X=0,Y=0,Width=279,5,Height=0}
parent:{X=0,Y=0,Width=320,Height=480}
hud:{X=0,Y=0,Width=320,Height=480}

失敗案例

parent:{X=0,Y=0,Width=320,Height=480}
hud:{X=0,Y=0,Width=0,Height=0}
parent - before setting up constraints{X=0,Y=0,Width=320,Height=480}
hud - after hud showing: {X=-20,Y=59,Width=279,5,Height=0}

因此,在正常情況下, LayoutSubviews似乎被調用了兩次,因為在那里會輸出parent:hud:行。 -20來自我使用的一個約束,我通過使用不同的約束(限制寬度/高度)在接下來的步驟之一中擺脫了這個約束。

如果我增加了最小高度,則可以在表格視圖左上方的導航欄下方看到平移,但它會通過導航欄切斷並且不會居中。 如果我嘗試將寬度/高度限制在零到我定義的最大大小之間,則會發生相同的行為:

NSLayoutConstraint widthConstraint1 = NSLayoutConstraint.Create(this.hudContainer, NSLayoutAttribute.Width, NSLayoutRelation.LessThanOrEqual, this, NSLayoutAttribute.Width, 1, -40);
widthConstraint1.Priority = 750;
NSLayoutConstraint widthConstraint2 = NSLayoutConstraint.Create(this.hudContainer, NSLayoutAttribute.Width, NSLayoutRelation.GreaterThanOrEqual, null, NSLayoutAttribute.NoAttribute, 1, 0);
widthConstraint2.Priority = 1000;
NSLayoutConstraint heightConstraint1 = NSLayoutConstraint.Create(this.hudContainer, NSLayoutAttribute.Height, NSLayoutRelation.LessThanOrEqual, this, NSLayoutAttribute.Height, 1, -100);
heightConstraint1.Priority = 750;
NSLayoutConstraint heightConstraint2 = NSLayoutConstraint.Create(this.hudContainer, NSLayoutAttribute.Height, NSLayoutRelation.GreaterThanOrEqual, null, NSLayoutAttribute.NoAttribute, 1, 0);
heightConstraint2.Priority = 1000;
AddConstraints(new NSLayoutConstraint[] { widthConstraint1, widthConstraint2, heightConstraint1, heightConstraint2});

在此不考慮最大寬度。

我使用此代碼將hud添加為子視圖並設置主要約束:

this.TranslatesAutoresizingMaskIntoConstraints = false;
this.parentView.AddSubview(this);

NSMutableDictionary viewsDictionary = new NSMutableDictionary();
viewsDictionary["hud"] = this;

this.parentView.LayoutIfNeeded();
Console.WriteLine("parent - before setting up constraints" + this.parentView.Frame);

this.parentView.AddConstraint(NSLayoutConstraint.Create(this, NSLayoutAttribute.Width, NSLayoutRelation.Equal, this.parentView, NSLayoutAttribute.Width, 1, 0));
this.parentView.AddConstraint(NSLayoutConstraint.Create(this, NSLayoutAttribute.Height, NSLayoutRelation.Equal, this.parentView, NSLayoutAttribute.Height, 1, 0));
this.parentView.AddConstraint(NSLayoutConstraint.Create(this, NSLayoutAttribute.Top, NSLayoutRelation.Equal, this.parentView, NSLayoutAttribute.Top, 1, 0));
this.parentView.AddConstraint(NSLayoutConstraint.Create(this, NSLayoutAttribute.Right, NSLayoutRelation.Equal, this.parentView, NSLayoutAttribute.Right, 1, 0));
this.parentView.AddConstraint(NSLayoutConstraint.Create(this, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, this.parentView, NSLayoutAttribute.Bottom, 1, 0));
this.parentView.AddConstraint(NSLayoutConstraint.Create(this, NSLayoutAttribute.Left, NSLayoutRelation.Equal, this.parentView, NSLayoutAttribute.Left, 1, 0));
this.parentView.AddConstraint(NSLayoutConstraint.Create(this, NSLayoutAttribute.CenterX, NSLayoutRelation.Equal, this.parentView, NSLayoutAttribute.CenterX, 1, 0));
this.parentView.AddConstraint(NSLayoutConstraint.Create(this, NSLayoutAttribute.CenterY, NSLayoutRelation.Equal, this.parentView, NSLayoutAttribute.CenterY, 1, 0));

這是用於刪除和隱藏hud的代碼:

this.Alpha = 0.0f;
RemoveFromSuperview();

我的想法不多了。 我怎么解決這個問題? 也許有人可以給我一個提示,我該如何更好地調試它。 此處提供的代碼在C#中,但是您可以在Objective-C / Swift中提供代碼示例!

您不應該將視圖手動添加到UIViewControllerWrapperView因為它是內部API。 這樣做可能導致不可預測的結果。

而是將您的加載指示器作為子視圖添加到UITableViewControllerview屬性中。 也許這已經解決了您的問題。

還有一件事:如果HUD是UIActivityIndicatorView ,則無需刪除它即可將其隱藏。 只需將hidesWhenStopped屬性設置為true 那么該指標將在stopAnimating時自動隱藏,並在startAnimating時重新出現。

編輯:

正如您所指出的,將HUD直接添加到視圖可能會導致定位問題。 解決此問題的一種方法是手動設置一個包含表視圖和HUD的容器視圖(普通的UIView ):

override func viewDidLoad() {
  super.viewDidLoad()

  let tableView = self.tableView
  let containerView = UIView(frame: self.view.bounds)
  containerView.addSubview(tableView)
  containerView.addSubview(spinner)      
  view = containerView

  spinner.translatesAutoresizingMaskIntoConstraints = false
  view.addConstraint(NSLayoutConstraint(item: spinner, attribute: .CenterX, relatedBy: .Equal, toItem: view, attribute: .CenterX, multiplier: 1, constant: 0))
  view.addConstraint(NSLayoutConstraint(item: spinner, attribute: .CenterY, relatedBy: .Equal, toItem: view, attribute: .CenterY, multiplier: 1, constant: 0))

  spinner.startAnimating()
}

請注意,此示例使用了一個簡單的活動指示器,該指示器具有內在的大小,因此要使其居中,只需要兩個約束即可; 對於HUD,您可能必須添加更復雜的約束。

我采用了dr_barto建議的方法。 我定義了新的基類HUDTableViewController ,這是我的新UITableViewController 所以我從HUDTableViewController而不是UITableViewController HUDTableViewController子類。

我的HUD獲得以下視圖:

TableView.Superview (在我的子類HUDTableViewController內部)

人們將不得不添加其他方法,並為UICollectionViewController實現此類基類。 在這里,我為UITableViewController提供了一個示例:

public class HUDTableViewController : UIViewController, IUITableViewDataSource, IUITableViewDelegate, IDisposable
{
    private UITableView tableView;

    public UITableView TableView
    {
        get
        {
            return this.tableView;
        }
        set
        {
            this.tableView = value;
        }
    }

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        this.tableView = new UITableView();
        this.tableView.TranslatesAutoresizingMaskIntoConstraints = false;

        this.tableView.WeakDelegate = this;
        this.tableView.WeakDataSource = this;

        UIView parentView = new UIView();
        parentView.AddSubview(this.tableView);
        View = parentView;

        NSMutableDictionary viewsDictionary = new NSMutableDictionary();
        viewsDictionary["parent"] = parentView;
        viewsDictionary["tableView"] = this.tableView;

        parentView.AddConstraints(NSLayoutConstraint.FromVisualFormat("H:|[tableView]|", (NSLayoutFormatOptions)0, null, viewsDictionary));
        parentView.AddConstraints(NSLayoutConstraint.FromVisualFormat("V:|[tableView]|", (NSLayoutFormatOptions)0, null, viewsDictionary));
    }

    [Foundation.Export("numberOfSectionsInTableView:")]
    public virtual System.nint NumberOfSections(UIKit.UITableView tableView)
    {
        throw new NotImplementedException();
    }

    public virtual System.nint RowsInSection(UIKit.UITableView tableview, System.nint section)
    {
        throw new NotImplementedException();
    }

    public virtual UIKit.UITableViewCell GetCell(UIKit.UITableView tableView, Foundation.NSIndexPath indexPath)
    {
        throw new NotImplementedException();
    }

    [Foundation.Export("tableView:didSelectRowAtIndexPath:")]
    public virtual void RowSelected(UIKit.UITableView tableView, Foundation.NSIndexPath indexPath)
    {
        throw new NotImplementedException();
    }

    [Foundation.Export("tableView:heightForHeaderInSection:")]
    public virtual System.nfloat GetHeightForHeader(UIKit.UITableView tableView, System.nint section)
    {
        throw new NotImplementedException();
    }

    [Foundation.Export("tableView:viewForHeaderInSection:")]
    public virtual UIKit.UIView GetViewForHeader(UIKit.UITableView tableView, System.nint section)
    {
        throw new NotImplementedException();
    }

    [Foundation.Export("tableView:willDisplayCell:forRowAtIndexPath:")]
    public virtual void WillDisplay(UIKit.UITableView tableView, UIKit.UITableViewCell cell, Foundation.NSIndexPath indexPath)
    {
        throw new NotImplementedException();
    }
}

可以看到,我在UITableView后面添加了一個附加視圖。 現在,我可以將表視圖的超級視圖用於HUD。 到目前為止似乎工作正常。

惰性替代方案(具有不同的行為):

  • 使用Window屬性:

    UIApplication.SharedApplication.Delegate.GetWindow().View

  • 使用NavigationController

    NavigationController.View

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM