Jak określić rozmiar dostosowanego obrazu krawędzi do krawędzi iPhone ' a 6/7?

Powiedzmy, że chcę, aby obraz w pakiecie zajmował całą dostępną szerokość ekranu w aplikacji na iPhone ' a - na przykład baner. I ' d create my_banner.png with width 320px, [email protected] z szerokością 640px i [email protected] dla iPhone 6 plus z szerokością 1242px. Ale rozdzielczość iPhone 6 to 750×1334 piksele. Mimo to dzieli przyrostek @2x z iPhone 4 i 5, które mają 640px szerokość.

Jaki jest zalecany sposób lub dobry sposób , aby określić plik obrazu, który został zoptymalizowany dla 750px szerokości iPhone 6 ? Wygląda na to, że nie można tego zrobić w asset catalog? Czy powinno się to robić programowo? Czy jest jakiś inny przyrostek, który można użyć dla iPhone 6?

iPhone 4,5,6 rozmiary ekranu (Obrazek zaczerpnięty z http://www.iphoneresolution.com )

Author: Niklas Berglund, 2014-09-17

12 answers

Wydaje mi się, że wiele z tych odpowiedzi chce rozwiązać, jak ograniczyć imageView, gdzie myślę, że jesteś zainteresowany ładowaniem odpowiedniego pliku multimedialnego? Chciałbym wymyślić własne rozwiązanie rozszerzalne przyszłości, coś w tym stylu:

"UIImage+DeviceSpecificMedia.h " - (Kategoria na UIImage)

Interfejs:

#import <UIKit/UIKit.h>

typedef NS_ENUM(NSInteger, thisDeviceClass) {

    thisDeviceClass_iPhone,
    thisDeviceClass_iPhoneRetina,
    thisDeviceClass_iPhone5,
    thisDeviceClass_iPhone6,
    thisDeviceClass_iPhone6plus,

    // we can add new devices when we become aware of them

    thisDeviceClass_iPad,
    thisDeviceClass_iPadRetina,


    thisDeviceClass_unknown
};

thisDeviceClass currentDeviceClass();

@interface UIImage (DeviceSpecificMedia)

+ (instancetype )imageForDeviceWithName:(NSString *)fileName;

@end

Realizacja:

#import "UIImage+DeviceSpecificMedia.h"

thisDeviceClass currentDeviceClass() {

    CGFloat greaterPixelDimension = (CGFloat) fmaxf(((float)[[UIScreen mainScreen]bounds].size.height),
                                                    ((float)[[UIScreen mainScreen]bounds].size.width));

    switch ((NSInteger)greaterPixelDimension) {
        case 480:
            return (( [[UIScreen mainScreen]scale] > 1.0) ? thisDeviceClass_iPhoneRetina : thisDeviceClass_iPhone );
            break;
        case 568:
            return thisDeviceClass_iPhone5;
            break;
        case 667:
            return thisDeviceClass_iPhone6;
            break;
        case 736:
            return thisDeviceClass_iPhone6plus;
            break;
        case 1024:
            return (( [[UIScreen mainScreen]scale] > 1.0) ? thisDeviceClass_iPadRetina : thisDeviceClass_iPad );
            break;
        default:
            return thisDeviceClass_unknown;
            break;
    }
}

@implementation UIImage (deviceSpecificMedia)

+ (NSString *)magicSuffixForDevice
{
    switch (currentDeviceClass()) {
        case thisDeviceClass_iPhone:
            return @"";
            break;
        case thisDeviceClass_iPhoneRetina:
            return @"@2x";
            break;
        case thisDeviceClass_iPhone5:
            return @"-568h@2x";
            break;
        case thisDeviceClass_iPhone6:
            return @"-667h@2x"; //or some other arbitrary string..
            break;
        case thisDeviceClass_iPhone6plus:
            return @"-736h@3x";
            break;

        case thisDeviceClass_iPad:
            return @"~ipad";
            break;
        case thisDeviceClass_iPadRetina:
            return @"~ipad@2x";
            break;

        case thisDeviceClass_unknown:
        default:
            return @"";
            break;
    }
}

+ (instancetype )imageForDeviceWithName:(NSString *)fileName
{
    UIImage *result = nil;
    NSString *nameWithSuffix = [fileName stringByAppendingString:[UIImage magicSuffixForDevice]];

    result = [UIImage imageNamed:nameWithSuffix];
    if (!result) {
        result = [UIImage imageNamed:fileName];
    }
    return result;
}

@end
 43
Author: Jef,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-06 05:08:25

Używam poniższej sztuczki, ponieważ niektóre rzeczy faktycznie działają:

  • katalog zasobów dla konkretnych urządzeń
  • Określ obrazy dla 1x, 2x na podstawie 320x640
  • Określ obrazy dla 4 2x i 3x na podstawie 320x568 (iPhone 5)
  • W przeciwieństwie do iPhone 'a 6, nie jest to urządzenie, które nie jest kompatybilne z iPhone' em 6, ponieważ jest to jedyne urządzenie, które sprawia problemy z wiązaniem krawędzi na krawędź.]}
  • Udostępnij tylko 2x obraz dla iPhone 6 w pełnej rozdzielczości (750x1334)

Zadeklaruj stałą

#define IS_IPHONE_6 [[UIScreen mainScreen]nativeBounds].size.width == 750.0 ? true : false

I użyj go tak:

UIImage *image = [UIImage imageNamed:@"Default_Image_Name"];
if(IS_IPHONE_^) {
    image = [UIImage imageNamed:@"Iphone6_Image_Name"];
}

To może nie być najpiękniejsze rozwiązanie, ale działa, przynajmniej tak długo, jak apple nie zapewnia lepszego API dla wiązań krawędzi do krawędzi.

 4
Author: Sebastian Flückiger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-22 06:29:07

Układ Automatyczny ma pomóc w tej sytuacji..

Teraz powiedz mi @ Nicklas Berglund co byś zrobił, gdyby urządzenie się obróciło? Powiedzmy, że jesteś teraz w trybie poziomym.. Jak wypełnić poziomą przestrzeń, która nie znajduje się już w zasobach obrazu?

Tylko pokarm dla myśli.. Układ automatyczny ma dbać o ekran bez względu na orientację lub urządzenie, na którym jest uruchomiona aplikacja..

Może Apple powinno zacząć celować w orientacje urządzeń w aktywa wizerunkowe w przyszłości?

Wróćmy do twojego pytania.. Rozwiązaniem jest zastąpienie obrazów @2x obrazami o szerokości 750px, a następnie automatyczne układanie wykonuje swoje zadanie. O tak, to jest najtrudniejsza część..

Jeśli dodasz ograniczenia, aby je dopasować, wyciśnie je poziomo, gdy zostanie wyświetlone na ekranie 4", ale możesz użyć mnożników, aby odpowiednio przeskalować obraz. Oto jak możesz to zrobić:

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[imageFooterView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(imageFooterView)]];

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[imageFooterView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(imageFooterView)]];


float aspectRatio = imageFooterView.frame.size.height/imageFooterView.frame.size.width;

[imageFooterView addConstraint:[NSLayoutConstraint constraintWithItem:imageFooterView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:imageFooterView attribute:NSLayoutAttributeWidth multiplier:aspectRatio constant:0.0f]];
 2
Author: Bms270,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-16 04:11:34

Nie mogłem znaleźć sposobu, aby to zrobić, ponieważ miałem obraz tła, który był idealnie dopasowany do katalogu zasobów na każdym urządzeniu z wyjątkiem iPhone 6. Moja poprawka(zrobiłem to w SpriteKit)?

if (bgNode.size.width != self.frame.size.width) {
        bgNode.texture = [SKTexture textureWithImageNamed:@"i6bg.png"];
        [bgNode runAction:[SKAction scaleXTo:self.frame.size.width/bgNode.size.width y:self.frame.size.width/bgNode.size.height duration:.1]];
    }

BgNode jest obrazem tła, który jest pobierany przez urządzenie. Jeśli jest to iPhone 6, nie zmieści się na ekranie, a więc szerokość obrazu tła nie będzie taka sama jak szerokość ekranu. Gdy urządzenie jest rozpoznawane jako iPhone 6, zmieniam teksturę na teksturę R4 (@2x dla siatkówki) i przeskalować do odpowiednich wymiarów.

Próbowałem zrobić to samo ze zwykłym obrazem @2x, ale wyskalowany obraz wyglądał bardzo źle (był zbyt rozciągnięty i zauważalny). Przy skalowaniu tekstury R4 proporcje szerokości/wysokości są nieco lepsze, więc zmiana nie jest nawet zauważalna. Mam nadzieję, że to daje jakiś pomysł, co można zrobić, zanim Apple dodaje aktywa iPhone 6.

 1
Author: Andriko13,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-22 04:37:25

Mam nadzieję, że rozwiąże to wszystkie problemy związane z dostosowanym obrazem krawędzi do krawędzi.
Xcode 6 - xcassets do uniwersalnej obsługi obrazu

Upewnij się, że jeśli używasz układu automatycznego, to zaznacz pin jest ustawiony na zero dla wszystkich krawędzi, a ograniczenia marginesu nie są zaznaczone.

Możesz również odwiedzić ten link do zdjęć ekranu startowego:
http://www.paintcodeapp.com/news/iphone-6-screens-demystified
http://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions

Tutaj wpisz opis obrazka

 1
Author: Dhaivat Vyas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:30:33

Podniosłem to samo pytanie do pomocy technicznej apple i potwierdzają, że dla pełnoekranowego obrazu nie można tego zrobić w katalogu zasobów: "obecnie nie ma możliwości, aby katalog zasobów załadował obrazy specyficzne dla urządzenia. Jeśli Twoja aplikacja musi obsługiwać obrazy specyficzne dla urządzenia, musisz zaimplementować własny kod, aby wykryć rozmiar ekranu i wybrać odpowiedni obraz. Możesz złożyć wniosek o ulepszenie, korzystając z poniższego łącza. Pamiętaj, aby wyjaśnić przypadek użycia tej funkcji. "

 1
Author: Qiulang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-13 02:16:37

Sprawdziłem konwencję nazewnictwa obrazu startowego wygenerowanego z katalogu zasobów za pomocą Xcode 6, a wersja krajobrazowa dla iPhone 6+, na przykład, miała: LaunchImage-Landscape-736h@3x.png

Bazując na tym, zakładam, że dla urządzeń retina będzie to wyglądało następująco, zakładając plik bazowy .png:

  • desert@2x : iPhone 4s (320 x 420)
  • desert-568h@2x: iPhone 5, 5C i 5S (320 x 568)
  • desert-667h@2x : iPhone 6 (375 x 667)
  • desert-736h@3x : iPhone 6+ (414 x 736)
  • desert@2x ~ ipad: iPad (1024 x 768)
 0
Author: Benzi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-10 12:20:59

Nie ma natywnej obsługi zasobów w tym przypadku, więc myślę, że lepiej byłoby zrobić to ręcznie, ponieważ praca z nieudokumentowanymi nazwami plików może łatwo pęknąć w przyszłości.

 0
Author: Rivera,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-27 02:54:09

Wystarczy zmierzyć wymiary urządzenia i wywołać obraz, który chcesz. ie zrób to programowo

Więc w Twoim appdelegate mają globals

deviceHeight = self.window.frame.size.height;
deviceWidth = self.window.frame.size.width;
Możesz dzwonić wielokrotnie. Następnie sprawdź je i wywołaj odpowiedni obraz
if (deviceWidth == 640){
image = IPHONE4IMAGE;
deviceString = @"iPhone4";
}
else...
 0
Author: AMAN77,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-31 16:47:35

W moim przypadku byłem zainteresowany tym, aby moja podstawowa podklasa kontrolera widoku miała taki sam obraz tła, jak mój obraz startowy.

UWAGA: takie podejście nie zadziała, chyba że jest to twoje specyficzne wymagania.

Również, nawet gdy próbowałem stworzyć obraz tła o odpowiednim rozmiarze dla iPhone 6 (750x1334), Ładowanie tego obrazu jako obrazu wzorca do koloru tła dla widoku skończyło się skalowaniem obrazu w niepożądany sposób sposób.

Ta odpowiedź dała mi kod, którego potrzebowałem, aby znaleźć dla mnie dobre rozwiązanie.

Oto kod, który mam, aby mój obraz startowy pasował do mojego obrazu tła UIViewController (lub odwrotnie):

- (void)viewDidLoad {
    [super viewDidLoad];
    UIImage *background         = [UIImage imageNamed:[self splashImageName]];
    UIColor *backgroundColor    = [UIColor colorWithPatternImage:background];
    self.view.backgroundColor   = backgroundColor;
}
- (NSString *)splashImageName {
    UIInterfaceOrientation orientation  = [[UIApplication sharedApplication] statusBarOrientation];
    CGSize viewSize                     = self.view.bounds.size;
    NSString *viewOrientation           = @"Portrait";
    if (UIDeviceOrientationIsLandscape(orientation)) {
        viewSize                        = CGSizeMake(viewSize.height, viewSize.width);
        viewOrientation                 = @"Landscape";
    }
    NSArray *imagesDict                 = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"UILaunchImages"];
    for (NSDictionary *dict in imagesDict) {
        CGSize imageSize                = CGSizeFromString(dict[@"UILaunchImageSize"]);
        if (CGSizeEqualToSize(imageSize, viewSize) && [viewOrientation isEqualToString:dict[@"UILaunchImageOrientation"]])
            return dict[@"UILaunchImageName"];
    }
    return nil;
}
 0
Author: mbm29414,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:30:33

Proszę spróbować tej klasy, aby programowo zmienić nazwę obrazu.

import UIKit

class AGTools: NSObject {
    class func fullWidthImage(imageName: String!) -> String!{
        let screenWidth = UIScreen.mainScreen().bounds.size.width
        switch (screenWidth){
        case 320:
            // scale 2x or 1x
            return (UIScreen.mainScreen().scale > 1.0) ? "\(imageName)@2x" : imageName
        case 375:
            return "\(imageName)-375w@2x"
        case 414:
            return "\(imageName)-414w@3x"
        default:
            return imageName
        }
    }
}

Użyj tej metody w ten sposób.

_imgTest.image = UIImage(named: AGTools.fullWidthImage("imageName"))
 0
Author: Aspgod,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-29 15:58:04

Po pierwsze ze wszystkich, musisz skonfigurować imageView tak, aby obejmował cały ekran, Autolayout bardzo pomoże w tym zadaniu, spójrz na link poniżej i dowiedz się, jak przypiąć ograniczenia (wiodąca przestrzeń, końcowa przestrzeń, Górna przestrzeń i dolna przestrzeń) za pomocą Storyboardów :

Http://www.thinkandbuild.it/learn-to-love-auto-layout/

Tutaj wpisz opis obrazka

Drugi krok to tworzenie zestawów obrazów specyficznych dla urządzenia na zasobach obrazu (image poniżej), aby wyświetlić różne obrazy w zależności od urządzenia.

Tutaj wpisz opis obrazka

Zobacz tę infografikę: http://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions

Wyjaśnia różnice między starymi iPhone ' ami, iPhone 6 i iPhone 6 Plus. Możesz zobaczyć Porównanie rozmiarów ekranu w punktach, renderowanych pikselach i fizycznych pikselach

To wszystko

Tutaj wpisz opis obrazka

Tutaj wpisz opis obrazka

Proszę o informację zwrotną w razie jakichkolwiek problemów.

 -2
Author: carantes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-01 22:43:47