Графические ошибки при программном создании UILabel, UITextField и т. Д.

Я программно создал представление входа в систему и представление таблицы.

При определенных обстоятельствах, которые я не могу воспроизвести, возникают странные визуальные ошибки:

  • Текст с некоторыми буквами, имеющими другой размер шрифта, чем другие
  • Кнопка, на которой граница изначально не отображается, а только при нажатии на нее. В этом же случае граница кнопки может отображаться в UITextField вместо заполнителя (см. Снимок экрана).
  • Ярлык отображается не в нужном месте, а в вышеупомянутом текстовом поле, перевернутым (мне еще не удалось сделать снимок экрана с этим)

Ниже я добавил два скриншота, на которых большая часть приложения была затемнена, показывая только ошибки:

http://uppix.net/b/c/4/dd1e41acb94b7d0ad8eb173772ea97.png > http://uppix.net/b/f/2/a5993440c07753b851701068330be.png

Здесь вы можете видеть, что текст смешивается с разными размерами шрифтов.

Эти ошибки возникают нерегулярно и не воспроизводятся.

Я добавил код экрана входа в систему ниже:

 // Implement loadView to create a view hierarchy programmatically, without 
 // using a nib.
     - (void)loadView {
     UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
     UIFont* font = [UIFont systemFontOfSize:14];

 float midLine = 100.0;
 float height = 30.0;
 float borderY = 70.0;
 float borderX = 10.0;
 float width = 320.0 - borderX * 2.0;
 float paddingX = 10.0;
 float paddingY = 5.0;

 CGRect usernameLabelRect = CGRectMake(borderX, borderY, midLine, height);
 CGRect usernameFieldRect = CGRectMake(borderX + midLine + paddingX, borderY, 
                               width - midLine - paddingX - 40 , height);

 CGRect passwordLabelRect = CGRectMake(borderX, borderY + height + paddingY,
                               midLine, height);
 CGRect passwordFieldRect = CGRectMake(borderX + midLine + paddingX, 
                               borderY + height + paddingY, 
                               width - midLine - paddingX - 40, height);

 CGRect loginButtonRect = CGRectMake(borderX + 40, 
                               borderY + height*2 + paddingY*2, width - 80, 
                               height);

 //CGRect warningRect =  CGRectMake(borderX,
 //                         borderY * height * 3.0 + paddingY *3.0, 
 //                         width, height);
 CGRect warningRect =  CGRectMake(borderX, 175, width, 40);

 UILabel* usernameLabel = [[UILabel alloc] initWithFrame:usernameLabelRect];

 usernameLabel.textAlignment = UITextAlignmentRight;
 usernameLabel.font = font;
 usernameLabel.text = @"Username:";

 UILabel* passwordLabel = [[UILabel alloc] initWithFrame:passwordLabelRect];
 passwordLabel.textAlignment = UITextAlignmentRight;
 passwordLabel.font = font;
 passwordLabel.text = @"Password:";


 usernameField = [[UITextField alloc] initWithFrame:usernameFieldRect];
 [usernameField setBorderStyle:UITextBorderStyleRoundedRect];
 //[usernameField setPlaceholder:@"<Username>"];
 usernameField.font = font;
 usernameField.autocapitalizationType = UITextAutocapitalizationTypeNone;
 usernameField.autocorrectionType = UITextAutocorrectionTypeNo;

 passwordField = [[UITextField alloc] initWithFrame:passwordFieldRect];
 passwordField.font = font;
 [passwordField setBorderStyle:UITextBorderStyleRoundedRect];
 //[passwordField setPlaceholder:@"<Password>"];
 passwordField.autocapitalizationType = UITextAutocapitalizationTypeNone;
 passwordField.autocorrectionType = UITextAutocorrectionTypeNo;
 passwordField.secureTextEntry = YES;

 loginButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
 loginButton.frame = loginButtonRect;
 [loginButton setTitle: @"Einloggen" forState:UIControlStateNormal];
 [loginButton setTitleColor:[UIColor blackColor]
                                    forState:UIControlEventTouchDown];
 loginButton.contentVerticalAlignment =
                                    UIControlContentVerticalAlignmentCenter;
 loginButton.contentHorizontalAlignment =
                                    UIControlContentHorizontalAlignmentCenter;
 [loginButton addTarget:self action:@selector(OnLoginClicked:)
                          forControlEvents:UIControlEventTouchUpInside];
 [loginButton setBackgroundColor:[UIColor clearColor]];

 warningLabel = [[UILabel alloc] initWithFrame:warningRect];
 warningLabel.font = font;
 warningLabel.numberOfLines = 3;
 warningLabel.text =
 @"Wenn Sie die Applikation jetzt schließen, so werden Ihre Logindaten verworfen.";

 [myView addSubview:usernameLabel];
 [myView addSubview:passwordLabel];
 [myView addSubview:usernameField];
 [myView addSubview:passwordField];
 [myView addSubview:loginButton];
 [myView addSubview:warningLabel];
 /*
 [usernameLabel release];
 [passwordLabel release];
 [usernameField release];
 [passwordField release];
 [loginButton release];
 [warningLabel release];
 */
 self.view = myView;
 [myView release];
}

person Tomen    schedule 03.11.2009    source источник
comment
Опубликованный вами экран входа в систему является ярким примером того, почему следует использовать Interface Builder. Вы в основном просто размещаете некоторые элементы управления и устанавливаете множество свойств, которые могли бы быть обработаны Interface Builder. Сделать отдельный Xib для представления входа и загрузить его при необходимости - это правильный путь. Самостоятельная настройка представления в коде подвержена ошибкам и намного более наглядна. Упрощает обнаружение проблем заранее из-за перекрывающихся элементов управления и тому подобного. Зачем вам нужно настраивать это в коде?   -  person Yannick Compernol    schedule 04.11.2009


Ответы (2)


Я не могу работать с позиционированием всего вашего экрана в голове, но мне кажется, что многие из ваших полей перекрываются: это намеренно? Может в этом причина? Обычно я создаю представления в коде, но это может быть один из случаев для IB!

Вы не показали никакого кода для табличного представления, однако раньше у меня возникали аналогичные проблемы, когда вы добавляли подпредставления в ячейку, а затем, когда в следующий раз, когда ячейка удаляется из очереди с помощью DequeueReusableCell, вы снова добавляете подпредставления, не проверяя, есть ли они или очищая их. . Это приводит к всевозможным перекрытиям, как и на первом скриншоте.

person Andiih    schedule 03.11.2009

Проблема заключалась в том, что я вызвал сообщения UIKit из Not-The-Main-Thread, что вызывает всевозможные графические проблемы. Решил это с помощью performSelectorOnMainThread: в нескольких местах моего кода =)

person Tomen    schedule 20.11.2009