我正在尝试在UITableViewController
之上显示加载指示符。因此,我将我的子视图添加到myTableViewontroller.View.Superview
UIViewControllerWrapperView
。到目前为止,这种方法有效,但并非在所有情如果第一次在导航堆栈中添加UITableViewController
,我可以根据需要随时显示加载指示符。如果我弹出UITableViewController
并再次在导航堆栈上推送它的新实例,则不会显示加载指示符。连续调用使加载指示符再次出现!
我尝试在UpdateConstraints
,LayoutSubviews
中设置我的约束,但它没有帮助。不知何故,框架的高度似乎为零。检查框架显示以下内容:
正常情况:
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 来自我使用的一个约束,我通过使用不同的约束(限制widht / height)在后续步骤之一中消除了这些约束。
如果我添加一个最小高度,我可以在表格视图左上角的导航栏下看到hud,但是它会通过导航栏切断并且不居中。如果我尝试限制零和我定义的最大大小之间的宽度/高度,则会出现相同的行为:
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中提供代码示例!
答案 0 :(得分:2)
您不应手动向UIViewControllerWrapperView
添加视图,因为它是内部API。这样做会导致不可预测的结果。
相反,请将加载指标作为子视图添加到view
的{{1}}属性中。也许这已经解决了你的问题。
还有一件事:如果你的HUD是UITableViewController
,你不需要删除它来隐藏它。只需将UIActivityIndicatorView
属性设置为hidesWhenStopped
;然后,在调用true
时,指标会自动隐藏,并在调用stopAnimating
时重新显示。
修改强>
正如您所指出的,直接将HUD添加到视图中会导致定位问题。解决此问题的一种方法是手动设置容纳表视图和HUD的容器视图(普通startAnimating
):
UIView
请注意,此示例使用具有固有大小的简单活动指示符,因此要使其居中,只需要两个约束;对于您的HUD,您可能需要添加更复杂的约束。
答案 1 :(得分:0)
我采用了dr_barto建议的方法。我定义了我的新基类HUDTableViewController
,这是我的新UITableViewController
。所以我从HUDTableViewController
而不是UITableViewController
进行了子类化。
我的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
后面添加了一个额外的视图。现在我可以使用表视图的superview来查看我的HUD。似乎到目前为止工作。
懒惰的替代品(具有不同的行为):
使用Window
属性:
UIApplication.SharedApplication.Delegate.GetWindow().View
使用NavigationController
:
NavigationController.View