Xamarin.iOS 为 UITextField/ViewDidAppear 的底部绘制边框为时已晚

Xamarin.iOS Draw a Border for bottom of the UITextField / ViewDidAppear is too late

我正在 Xamarin.iOs 中编码,我想为 UITextField 的底部添加边框。

所以很简单,我用谷歌搜索了一下(我将其个性化为 Xamarin.ios 并且)我从 link.

中获得了这段代码
UITextField _textField = new UITextField();
_textField.Placeholder = placeHolder;
_textField.AutocapitalizationType = autocap.Value;
_textField.AutocorrectionType = uitextAutocorrect.Value;
_textField.BorderStyle = borderstyle.Value;
_textField.SecureTextEntry = secureTextEntry.Value;
_textField.KeyboardType = uiKeyboardType.Value;
return _textField;

如您所知,我不能将这部分代码放入 ViewController 的构造函数中,也不能放入 ViewWillAppear 中。所以我必须把它放在 ViewDidAppear 中,BUT 来不及了,这意味着当我 运行 ViewController 时,它显示无边框的 textField,并且紧接着几毫秒后,边界就会出现,这对我来说太晚了。

对这个显示问题有什么想法吗?

编辑:

所以我更详细地问了我的问题:

这是我的完整代码:

public class 更改密码ViewController: UIViewController { //私人MainViewModel _viewModel;

    private UILabel _oldPasswordLabel;
    private UITextField _oldPasswordTextField;

    private UILabel _newPasswordLabel;
    private UITextField _newPasswordTextField;

    private UILabel _confirmPasswordLabel;
    private UITextField _confirmPasswordTextField;

    private User currentUser;

    private UIButton _saveNewPassworBtn;

    public ChangePasswordViewController(User user)
    {
        currentUser = user;
    }

    private void _saveNewPassworBtn_TouchUpInside(object sender, EventArgs e)
    {
        //do sth
    }


    public override void ViewDidLoad()
    {
        base.ViewDidLoad();
        // Perform any additional setup after loading the view, typically from a nib. 

        //_viewModel = new MainViewModel();

        Title = Texts.ChangePassword;
        View.BackgroundColor = UIColor.White;



        _oldPasswordLabel = InitUILabel(Texts.OldPasswordTxt, alignment: UITextAlignment.Right);
        _oldPasswordLabel.Font = UIFont.BoldSystemFontOfSize(14);
        _oldPasswordLabel.AdjustsFontSizeToFitWidth = true;
        _oldPasswordTextField = InitUITextField(Texts.OldPassword, secureTextEntry: true);
        this._oldPasswordTextField.ShouldReturn += (textField) => {
            _newPasswordTextField.BecomeFirstResponder();
            return true;
        };
        _oldPasswordTextField.BorderStyle = UITextBorderStyle.None;




        _newPasswordLabel = InitUILabel(Texts.NewPasswordTxt, alignment: UITextAlignment.Right);
        _newPasswordLabel.Font = UIFont.BoldSystemFontOfSize(14);
        _newPasswordTextField = InitUITextField(Texts.NewPassword, secureTextEntry: true);
        this._newPasswordTextField.ShouldReturn += (textField) => {
            _confirmPasswordTextField.BecomeFirstResponder();
            return true;
        };
        _newPasswordTextField.BorderStyle = UITextBorderStyle.None;



        _confirmPasswordLabel = InitUILabel(Texts.ConfirmPasswordTxt, alignment: UITextAlignment.Right);
        _confirmPasswordLabel.Font = UIFont.BoldSystemFontOfSize(14);
        _confirmPasswordTextField = InitUITextField(Texts.NewPassword, secureTextEntry: true);
        this._confirmPasswordTextField.ShouldReturn += (textField) => {
            textField.ResignFirstResponder();
            return true;
        };
        _confirmPasswordTextField.BorderStyle = UITextBorderStyle.None;





        _saveNewPassworBtn = InitUIButton(Texts.Save, _saveNewPassworBtn_TouchUpInside, Colors.MainColor, UIColor.White);

        View.AddSubviews(_oldPasswordLabel, _oldPasswordTextField, _newPasswordLabel, _newPasswordTextField,
                         _saveNewPassworBtn, _confirmPasswordLabel, _confirmPasswordTextField);

        //

        //constraints
        var hMargin = 10;
        var hMiniMargin = 5;
        var vMargin = 10;


       View.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();



        View.AddConstraints(
            _oldPasswordLabel.AtTopOf(View, 100),
            _oldPasswordLabel.AtLeftOf(View, hMargin),

            _oldPasswordTextField.Below(_oldPasswordLabel, hMiniMargin),
            _oldPasswordTextField.AtLeftOf(View, hMargin),
            _oldPasswordTextField.WithSameWidth(View).Minus(hMargin * 2),

            _newPasswordLabel.Below(_oldPasswordTextField, vMargin),
            _newPasswordLabel.AtLeftOf(View, hMargin),

            _newPasswordTextField.Below(_newPasswordLabel, hMiniMargin),
            _newPasswordTextField.AtLeftOf(View, hMargin),
            _newPasswordTextField.WithSameWidth(View).Minus(hMargin * 2),

            _confirmPasswordLabel.Below(_newPasswordTextField, vMargin),
            _confirmPasswordLabel.AtLeftOf(View, hMargin),

            _confirmPasswordTextField.Below(_confirmPasswordLabel, hMiniMargin),
            _confirmPasswordTextField.AtLeftOf(View, hMargin),
            _confirmPasswordTextField.WithSameWidth(View).Minus(hMargin * 2),

            _saveNewPassworBtn.Below(_confirmPasswordTextField, vMargin * 3),
            _saveNewPassworBtn.WithSameWidth(View).Minus(20),
            _saveNewPassworBtn.AtLeftOf(View, 10)

        );


        _newPasswordTextField = SetBottomBorderLine(_newPasswordTextField);
        _confirmPasswordTextField = SetBottomBorderLine(_confirmPasswordTextField);
        _oldPasswordTextField = SetBottomBorderLine(_oldPasswordTextField);
    }

    public override void ViewWillAppear(bool animated)
    {
        base.ViewWillAppear(animated);

        this.NavigationItem.SetLeftBarButtonItem(new UIBarButtonItem(Texts.Cancel,UIBarButtonItemStyle.Plain, (sender, args) =>
        {
            this.NavigationController.SetNavigationBarHidden(false, false);
            this.NavigationController.PushViewController(new ProfileViewController(), false);
        }), true);

    }
    public override void ViewDidAppear(bool animated)
    {
        base.ViewDidAppear(animated);

    }


} 

在这些行中:

_newPasswordTextField = SetBottomBorderLine(_newPasswordTextField); _confirmPasswordTextField = SetBottomBorderLine(_confirmPasswordTextField); _oldPasswordTextField = SetBottomBorderLine(_oldPasswordTextField);

我为我的文本字段设置了边框但是!如果我将这些行放在 ViewDidLoad 或 ViewWillAppear 或 ViewDidLayoutSubviews 中,它不会显示更改,如果我将它们放在 ViewDidAppear 中,它会完美显示并延迟几毫秒(在显示我的页面内容之后!!!)。你有什么解决办法吗?

使用Cirrious.FluentLayouts.

造成的

当我们在 ViewDidLoad 中设置 Constraints 时,那些控件将不会在 ViewDidAppear 之前完成渲染。

打印ViewDidLoadViewWillAppearViewDidAppear中那些textfields的frame,可以发现只有ViewDidAppear中的frame不等于(0,0 ,0,0).

解决问题,可以在ViewDidLoad中加入View.LayoutIfNeeded强制更新视图

View.AddConstraints(
    //xxx
);

View.LayoutIfNeeded(); //Add this 

_newPasswordTextField  = SetBottomBorderLine(_newPasswordTextField);
_confirmPasswordTextField  = SetBottomBorderLine(_confirmPasswordTextField);
_oldPasswordTextField  = SetBottomBorderLine(_oldPasswordTextField);