Принудительное расположение и размер макета в iOS Superviews
У меня огромная проблема, и я очень надеюсь, что вы поможете мне здесь... Я очень потерян в данный момент:(
У меня есть проект, который работает с MainWindow.xib. В моем файле делегата приложения я проверяю ориентацию устройства и загружаю соответствующий файл NIB, который имеет разные макеты (подпредставления) в зависимости от ориентации. Вот код для проверки ориентации:
-(void)checkTheOrientation
{
if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight)
{
viewController = [[[MyViewController alloc] initWithNibName:@"MyWideViewController" bundle:nil] autorelease];
NSLog(@"Landscape = MyWideViewController");
}
else if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortrait || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortraitUpsideDown)
{
viewController = [[[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil] autorelease];
NSLog(@"Portrait = MyViewController");
}
}
Это работает, как ожидалось, и в альбомной или книжной ориентации я загружаю правильные виды. Портретное представление загружается идеально, но альбомное представление загружается с толстым черным краем влево, как будто его положения x & y не установлены в 0 и 0 соответственно.
Вот портретное представление: http://uploads.socialcode.biz/2f25352B0e3x3z2t2z21 Вот альбомное представление с ошибкой: http://uploads.socialcode.biz/1G2k3T012d1z0Y1U2q1k
В файле MyViewController.m у меня есть грубое исправление, чтобы правильно сделать размер, чтобы избежать этой большой черной полосы слева. Вот код для этого:
- (void) performLayout {
// Ensure the main view is properly placed
NSInteger MaxSizeHeight, MaxSizeWidth;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
MaxSizeHeight = 1024;
MaxSizeWidth = 768;
}
if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight) {
CGRect mainViewFrame = [[self view] frame];
float width = mainViewFrame.size.width;
mainViewFrame.size.width = mainViewFrame.size.height;
mainViewFrame.size.height = width;
mainViewFrame.origin.x = 0;
mainViewFrame.origin.y = 0;
[[self view] setFrame:mainViewFrame];
} else {
CGRect mainViewFrame = [[self view] frame];
mainViewFrame.origin.x = MaxSizeWidth - mainViewFrame.size.width;
mainViewFrame.origin.y = MaxSizeHeight - mainViewFrame.size.height;
[[self view] setFrame:mainViewFrame];
}
// Ensure the content view is properly placed
CGRect contentFrame = [mainContentView frame];
if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight)
{
contentFrame.size.width = MaxSizeHeight;
contentFrame.size.height = MaxSizeWidth;
}
contentFrame.origin.x = 0;
contentFrame.origin.y = 44;
[mainContentView setFrame:contentFrame];
// Ensure the content subviews are properly placed
contentFrame.origin.y = 0;
for (UIView *contentView in [mainContentView subviews]) {
[contentView setFrame:contentFrame];
}
}
Проблема этого метода в том, что это просто очень плохой взлом, и он фактически не решает мою проблему. Когда он загружается в альбомной ориентации, он теперь изменяет размеры и позиционирует подпредставление в 1024x768,0,0, но любые дополнительные подпредставления, которые я загружаю через другие NIB, имеют ту же проблему.
Что я действительно хотел бы знать, так это то, как на самом деле я могу установить основное суперпредставление ландшафта равным 1024x768 в позициях 0 и 0, не пытаясь взломать это вместе и продолжать выполнять селектор executeLayout? На данный момент существует много противоречий с этим, поскольку хак на самом деле не правильно устанавливает размер суперпредставления, а просто подпредставления, которые я загружаю поверх суперпредставления.
Я подумал, что, возможно, такое простое исправление может решить проблему с супервизором, но, увы, нет: window.frame = CGRectMake(0, 0, 1024, 768);
Я просто хочу, чтобы мой главный суперпредставление было правильно размещено и измерено при загрузке, а затем суперпредставления просто загружаются в нужном месте. Пожалуйста, вы можете помочь мне здесь???
1 ответ
Во-первых, в UIView есть метод с именем -layoutSubviews
что вы можете переопределить, чтобы расположить подвиды так, как вам нравится. Он будет вызываться при первой загрузке вида и снова перед рисованием, если вы когда-нибудь отправите -setNeedsLayout
сообщение.
Во-вторых, вы должны быть в состоянии правильно установить эти позиции в файле.xib или раскадровке. Выберите ваш основной вид в его файле.xib и проверьте его положение в Инспекторе размера. Кроме того, убедитесь, что в инспекторе атрибутов для представления установлено горизонтальное расположение. Если все правильно, то происходит что-то еще. Чтобы упростить проблему, создайте новый проект в XCode с пустым представлением в альбомной ориентации. Я только что сделал один, и нет проблем с позицией. Это то, что вам нужно в вашем реальном приложении, поэтому выясните, что происходит в вашем реальном приложении, чтобы повлиять на положение представления, которого нет в вашем новом приложении-образце.