簡體   English   中英

如何為自定義UITableCell提供與內置單元格相同的布局指標的UITableView?

[英]How can I supply a custom `UITableCell` to an `UITableView` with the same layout metrics that a built-in cell would have?

當我將子視圖添加到原型表單元格時,假設是UITextView ,那么默認情況下沒有左邊界。 我希望它使用與iOS內部用於內置標准單元格布局相同的邊距。 萬一我遺漏了明顯的東西,“使用設備/ iOS默認值”標志在哪里? 否則,我的首選解決方案是一種查詢設備的設備相關和iOS版本相關的UI指標的方法。 出於此問題的目的,我們可以將其限制為僅UITableView控件及其UITableCell后代的度量。

這就是我生成自定義單元格的方式:

    internal class UITextSingleline : UITableViewCell
    {
        UILabel headingLabel;
        UITextView textBox;
        int MultiHeight;
        public bool secure; 

        public UITextSingleline() : this(null, 1) { }
        public UITextSingleline(int multiheight) : this(null, multiheight) { }
        public UITextSingleline(NSString cellId, int multiheight) : base(UITableViewCellStyle.Default, cellId) 
        {
            MultiHeight = multiheight;
            SelectionStyle = UITableViewCellSelectionStyle.None;            
            headingLabel = new UILabel()
            {
                Font = UIFont.SystemFontOfSize(16),
                TextColor = UIColor.DarkTextColor,
                BackgroundColor = UIColor.Clear
            };

            textBox = new UITextView()
            {                
                ClipsToBounds = true,
                Font = UIFont.SystemFontOfSize(16),
                TextColor = UIColor.DarkTextColor
            };

            if (multiheight == 1) textBox.TextContainer.MaximumNumberOfLines = 1;
            textBox.Layer.CornerRadius = 10.0f;
            textBox.Layer.BorderColor = UIColor.DarkTextColor.CGColor;
            textBox.Layer.BorderWidth = 1f;
            ContentView.AddSubviews(new UIView[] { headingLabel, textBox });               
        }

        public override void LayoutSubviews()
        {
            base.LayoutSubviews();
            headingLabel.Frame = new CGRect(16, 8, ContentView.Bounds.Width - 32, 20);
            textBox.Frame = new CGRect(16, 32, ContentView.Bounds.Width - 32, 36 * MultiHeight); /* see? magic numbers all over the place */
        }

        public void UpdateCell(string caption, string text)
        {            
            headingLabel.Text = caption;
            textBox.Text = text;                   
        }

        public string Text
        {
            get
            {
                return textBox?.Text;
            }
            set
            {
                if (textBox != null) textBox.Text = value;
            }
        }
    }

這是它如何鏈接到包含表視圖的方式:

public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
    switch (indexPath.Section)
    {
        case 0:
            /* area/workplace */
            switch (indexPath.Row)
            {
                case 0:
                    /* area picker (omitted) */
                case 1:
                    /* workplace text input (single-line) */
                    if (txtWorkplace == null)
                    {
                        txtWorkplace = new UITextSingleline();
                        txtWorkplace.UpdateCell("Workplace", Data.Instance.Payload.report.workplace);
                    }
                    return txtWorkplace;
            }
            break;
        case 1:
            /* rest ommitted for brevity */
            break;
    }
    return null;
}

我已經在SO和Internet上搜索了等效於系統度量的內容,其中有很多顏色和字體,但是我發現關於尺寸,邊距,插圖,角半徑等的信息很少:

  • 這個問題正好相反,它消除了任何余量,沒有提到如何復制iOS默認設置。
  • 這從蘋果開發頁面提到separatorInset整個財產TableView ,這似乎為左縮進工作,但我對應用度量布局到另一部分的一個部分有點懷疑。

硬編碼的幻數不是一個選擇。 我們在iPhone和iPad上進行了測試,發現即使在iOS版本不同的同一設備上,默認默認設置也有所不同。 只要它們在xamarin中正常翻譯后,我也會對Objective-C和Swift提示和解決方案感到滿意。

如果要根據不同的設備或不同的版本使用默認邊距,為什么不嘗試自動布局? NSLayoutAttribute.LeadingMargin表示元素空白的默認前緣。 在您的UITextSinglelineLayoutSubviews()從硬代碼修改為LayoutSubviews()布局:

假設單元格只有一個標簽來顯示一些文本:

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

    var leadingConstraint = NSLayoutConstraint.Create(headingLabel, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.LeadingMargin, 1.0f, 0);
    var topConstraint = NSLayoutConstraint.Create(headingLabel, NSLayoutAttribute.Top, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.TopMargin, 1.0f, 0);
    var trailingConstraint = NSLayoutConstraint.Create(headingLabel, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.TrailingMargin, 1.0f, 0);
    var bottomConstraint = NSLayoutConstraint.Create(headingLabel, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.BottomMargin, 1.0f, 0);

    ContentView.AddConstraints(new NSLayoutConstraint[] { leadingConstraint, topConstraint, trailingConstraint, bottomConstraint });
}

這樣, headingLabel將具有與“標准內置單元的TextLabel”相同的布局。

此外,就您而言,似乎您也想在單元格中添加一個UITextView 我建議您在構造函數時添加約束,我為您提供了以下約束:

public MyTableViewCell (IntPtr handle) : base (handle)
{
    headingLabel = new UILabel()
    {
        Font = UIFont.SystemFontOfSize(17),
        TextColor = UIColor.DarkTextColor,
        BackgroundColor = UIColor.Clear,
        Lines = 0
    };

    textBox = new UITextView()
    {
        ClipsToBounds = true,
        Font = UIFont.SystemFontOfSize(16),
        TextColor = UIColor.DarkTextColor
    };

    ContentView.AddSubview(headingLabel);
    ContentView.AddSubview(textBox);

    // Disable this to enable autolayout
    headingLabel.TranslatesAutoresizingMaskIntoConstraints = false;
    textBox.TranslatesAutoresizingMaskIntoConstraints = false;

    doLayouts();
}

void doLayouts()
{

    var leadingConstraint = NSLayoutConstraint.Create(headingLabel, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.LeadingMargin, 1.0f, 0);
    var topConstraint = NSLayoutConstraint.Create(headingLabel, NSLayoutAttribute.Top, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.TopMargin, 1.0f, 0);
    var trailingConstraint = NSLayoutConstraint.Create(headingLabel, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.TrailingMargin, 1.0f, 0);

    ContentView.AddConstraints(new NSLayoutConstraint[] { leadingConstraint, topConstraint, trailingConstraint });

    var boxLeading = NSLayoutConstraint.Create(textBox, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.LeadingMargin, 1.0f, 0);
    var boxTop = NSLayoutConstraint.Create(textBox, NSLayoutAttribute.Top, NSLayoutRelation.Equal, headingLabel, NSLayoutAttribute.Bottom, 1.0f, 4);
    var boxTrailing = NSLayoutConstraint.Create(textBox, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.TrailingMargin, 1.0f, 0);
    var boxBottom = NSLayoutConstraint.Create(textBox, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.BottomMargin, 1.0f, 0);
    var boxHeight = NSLayoutConstraint.Create(textBox, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1.0f, 36 * MultiHeight);

    ContentView.AddConstraints(new NSLayoutConstraint[] { boxLeading, boxTop, boxTrailing, boxBottom, boxHeight });
}

使用AutoLayout的另一個好處是:在將TableView的RowHeight設置為UITableView.AutomaticDimension和EstimatedHeight之后,如果我們設置正確的約束,則單元格將根據其內容自動計算行高。

暫無
暫無

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

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