Выпущены iOS 6 beta 4 и Xcode 4.5 Developer Preview 4 для разработчиков

Спустя три недели после выпуска iOS 6 beta 3, Apple выпустила четвертую бета-версию следующей операционной системы iOS для разработчиков. Новая бета-версия доступна для установки по воздуху (over-the-air) для тех, кто использует iOS 6 beta 3, а также должна быть доступна в Центре разработчиков Apple iOS.

Номер сборки — 10A5376e. Также были выпущены обновленная бета-версия Xcode и бета-версия iOS 6 для Apple TV.

Неясно, какие изменения внесены в эту новую бета-версию, но, вероятно, они связаны с исправлением ошибок и улучшением производительности. Мы будем изучать эту новую бета-версию и сообщим обо всех найденных новшествах. Если вы обнаружите что-то новое, вы можете сообщить нам по адресу tips@9to5mac.com.

Ожидается, что iOS 6 будет выпущена в середине или конце сентября, вместе с новым поколением iPhone, выпуск которого ожидается 21 сентября. Мероприятие, посвященное презентации нового iPhone и финальным деталям iOS 6, должно состояться в среду, 12 сентября.

iOS 6 будет выпущена для широкой публики этой осенью. Это крупное обновление, включающее более 200 новых функций. Среди них — совершенно новое приложение Maps с бэкендом Apple и функцией 3D Flyover, интеграция с Facebook, улучшенный Siri, расширенные функции телефона, улучшенный Safari, улучшенная почта и улучшения iCloud, такие как общие фотопотоки.

Примечания к выпуску после разрыва:

Следующие проблемы связаны с использованием iOS SDK 6.0 для разработки кода.

Фреймворк учетных записей

  • При запросе доступа к учетным записям Facebook единственным необходимым ключом в вашем словаре параметров является ACFacebookAppIdKey. ACFacebookPermissionGroupKey и ACFacebookAppVersionKey теперь устарели. Если вы запрашиваете разрешение на запись в соответствии с ACFacebookPermissionsKey, например publish_stream, вы должны предоставить значение для ACFacebookAudienceKey, которое может быть одним из ACFacebookAudienceEveryone, ACFacebookAudienceFriends или ACFacebookAudienceOnlyMe.

Адресная книга

  • ИСПРАВЛЕНО: Когда приложение находится в новом состоянии конфиденциальности и пытается представить ABNewPersonViewController, пользователь не может правильно закрыть этот контроллер представления, даже если пользователь разрешает доступ к контактам. Пользователь должен принудительно завершить работу приложения и перезапустить его.
  • Запрос доступа к контактам:
    • Пользователи могут предоставлять или запрещать доступ к данным контактов для каждого приложения. Чтобы запросить доступ к данным контактов, вызовите функцию ABAddressBookRequestAccessWithCompletion после вызова функции ABAddressBookCreateWithOptions. Функция ABAddressBookRequestAccessWithCompletion не блокирует приложение, пока у пользователя запрашивается разрешение или отказ в доступе. До предоставления доступа объект ABAddressBookRef не будет содержать никаких контактов, и любая попытка изменить контакты завершится ошибкой kABOperationNotPermittedByUserError. Пользователю будет предложено только при первом запросе доступа; последующие вызовы ABAddressBookCreateWithOptions будут использовать существующие разрешения. Обратный вызов будет вызван в произвольной очереди. Если объект ABAddressBookRef используется во всем приложении, то все использование должно быть передано в ту же очередь для использования ABAddressBookRef потокобезопасным образом.
  • Проверка статуса авторизации доступа:
    • Приложение может использовать API статуса авторизации, чтобы проверить, может ли оно получить доступ к контактам, календарям, напоминаниям или фотогалерее. Этот API не зависит от API запроса доступа и не будет запрашивать у пользователя разрешение или отказ в доступе. С помощью этого API приложение может настраивать отображение своих элементов пользовательского интерфейса, которые будут получать доступ к классу данных. Например, если доступ к контактам авторизован или еще не определен, то может быть отображена кнопка пользовательского интерфейса для выбора контакта.
    • Для адресной книги вызовите функцию ABAddressBookGetAuthorizationStatus. Для Event Kit вызовите метод класса authorizationStatusForEntityType: из EKEventStore. Для Assets Library вызовите метод класса authorizationStatus из ALAssetsLibrary. Значение возвращаемых статусов следующее:
      • Статус авторизации не определен — пользователь еще не принял решение о том, может ли это приложение получить доступ к классу данных.
      • Статус авторизации ограничен — это приложение не авторизовано для доступа к классу данных. Пользователь не может изменить статус этого приложения, возможно, из-за действующих ограничений, таких как родительский контроль.
      • Статус авторизации отклонен — пользователь явно отклонил доступ к классу данных для этого приложения.
      • Статус авторизации авторизован — это приложение авторизовано для доступа к классу данных.

Apple TV

  • ИСПРАВЛЕНО: В некоторых случаях экран может отображать неправильное разрешение. Перезапустите Apple TV, чтобы вернуть его к правильному разрешению.
  • ИСПРАВЛЕНО: Apple TV может перезагружаться при использовании приложения Remote.
  • ИСПРАВЛЕНО: Apple TV может перезагружаться при изменении системного языка.
  • ИСПРАВЛЕНО: Photo Stream не загружается при втором входе. Перезапустите Apple TV, чтобы решить проблему.
  • Музыка не воспроизводится во время слайд-шоу фотографий.
  • Заставка может вернуться к использованию изображений по умолчанию после установки обновления.

Bonjour

  • Класс NSNetService и API CFNetService по умолчанию не включают P2P-интерфейсы. Для поиска, регистрации или разрешения служб через P2P-интерфейсы приложению необходимо использовать API Bonjour DNSService*(), упомянутые ниже.
  • Установка параметра *interfaceIndex* в kDNSServiceInterfaceIndexAny в следующих API по умолчанию не будет включать P2P-интерфейсы. Чтобы включить P2P-интерфейсы, теперь вы должны установить флаг kDNSServiceFlagsIncludeP2P при использовании kDNSServiceInterfaceIndexAny или установить interfaceIndex в kDNSServiceInterfaceIndexP2P. Затронутые API:
    • DNSServiceBrowse
    • DNSServiceRegister
    • DNSServiceResolve
    • DNSServiceRegisterRecord
    • DNSServiceQueryRecord

Словарь

  • ИСПРАВЛЕНО: Существует известная проблема со словарями при попытке определения слова на любом языке, кроме английского или японского. Когда отображается справочная библиотека, пользователю предлагается загрузить словарь — эта загрузка может не начаться. Пользователь может нажать вне всплывающего окна на iPad или нажать кнопку «Готово» на iPhone или iPod touch, чтобы отменить запрос на загрузку.

Event Kit

  • Запрос доступа к календарям или напоминаниям:
    • Пользователи могут предоставлять или запрещать доступ к данным событий и напоминаний для каждого приложения. Чтобы запросить доступ к данным событий и/или напоминаний, вызовите метод requestAccessToEntityType:completion:: из EKEventStore. Это не заблокирует приложение, пока у пользователя запрашивается разрешение или отказ в доступе. До предоставления доступа для типа сущности хранилище событий не будет содержать календарей для этого типа сущности, и любая попытка сохранить данные завершится ошибкой.
    • Пользователю будет предложено только при первом запросе доступа; последующие экземпляры EKEventStore будут использовать существующие разрешения. Обратный вызов будет вызван в произвольной очереди.

Game Center

  • ИСПРАВЛЕНО: При создании новой учетной записи Game Center в приложении на iPad всплывающее окно для выбора месяца даты рождения отображается без контента для выбора.
  • Метод authenticate из GKLocalPlayer был удален. Аутентификация начнется автоматически при установке обратного вызова.
  • Начиная с iOS 6 beta 4, поддержка одиночных экземпляров GKGameCenterViewController больше не поддерживается.
  • Начиная с iOS 6 beta 4, GKScore+Sharing.h file и связанная категория удалены.

iCloud

  • При создании учетной записи iCloud вы можете использовать любой адрес электронной почты Apple ID или существующую учетную запись iCloud. Если у вас была учетная запись MobileMe, которую вы не перенесли в iCloud, вы можете использовать этот Apple ID для регистрации новой учетной записи iCloud (никакие из ваших предыдущих данных MobileMe не будут присутствовать).
    • Электронные адреса icloud.com теперь доступны для пользователей iCloud Mail. Пользователи, регистрирующие новые Apple ID или впервые активирующие Mail в своей учетной записи iCloud, автоматически получат электронный адрес @icloud.com вместо электронного адреса me.com. Пользователи iCloud с адресами @me.com, которые использовались с iOS 6 beta 3 или новее, получат электронный адрес @icloud.com, соответствующий их адресу @me.com.
    • Электронная почта icloud.com не может быть отправлена с icloud.com. Пользователям следует использовать icloud.com, если они хотят использовать веб-браузер для отправки электронной почты со своего адреса icloud.com.
    • Адреса @icloud.com будут добавлены в течение двух недель с момента первого использования iOS 6.
  • Профили подготовки должны быть включены для iCloud на портале подготовки iOS. Чтобы включить профиль подготовки для iCloud, перейдите в раздел App ID на портале подготовки iOS и настройте свой App ID для iCloud. После включения App ID для iCloud перегенерируйте профили подготовки, чтобы включить их для iCloud.
  • Метод setSortDescriptors: из NSMetadataQuery не поддерживается.
  • В iOS 6 файлы, защищенные Data Protection, не могут использоваться с API iCloud Storage.
  • Имена файлов не чувствительны к регистру в OS X, но чувствительны к регистру в iOS. Это может привести к проблемам при использовании iCloud для обмена файлами между двумя платформами. В iOS вы должны предпринять шаги, чтобы избежать создания файлов с именами, отличающимися только регистром.
  • Поведение согласованных операций чтения для iCloud Documents изменилось:В предыдущих версиях iOS, когда ваше приложение выполняло согласованную операцию чтения файла или пакета, а демон iCloud обнаруживал, что имеется более новая версия элемента, согласованная операция чтения блокировалась до тех пор, пока более новая версия элемента не была загружена и записана на диск.Начиная с iOS 6 beta 3, когда вы начинаете согласованную операцию чтения файла или пакета, для которого у вас уже есть локальная версия, согласованное чтение будет предоставлено как можно скорее, а новая версия, если она существует, будет загружена в фоновом режиме. Этот вызов будет заблокирован по причинам загрузки только в том случае, если у вас нет доступной локальной версии файла.

    Кроме того, когда файл имеет конфликты, демон iCloud не будет ждать, пока у него появятся все проигравшие в конфликте файлы, чтобы сделать файл доступным для вашего приложения. Он предоставит различные версии конфликтующего файла, как только сможет. Ваше приложение может использовать существующую координацию файлов и обратные вызовы UIDocument, чтобы получать уведомления о загрузке и доступности проигравших в конфликте.

iTunes

  • Для iOS SDK 6.0 требуется iTunes 10.6.3.
  • Предыдущие публичные бета-версии iOS больше не могут загружать песни iTunes Match.

Местоположение

  • В iOS 6 beta 4 были внесены изменения в новый перечислитель CLActivityType в Core Location:

Карты

  • В iOS 6 и более поздних версиях Map Kit построен на новой инфраструктуре, размещенной Apple. Более ранние версии iOS будут продолжать использовать сервис Google.
    • Совместимость API будет сохранена (см. известные проблемы ниже).
    • Карты теперь поддерживаются в симуляторе.
    • Данные карт будут продолжать развиваться — доступно лишь ограниченное количество спутниковых снимков высокого разрешения.
  • Приложения для построения маршрутов, не указывающие файл покрытия во время разработки, всегда будут отображаться в результатах поиска маршрутов на Картах.
  • Тестирование и отладка файлов покрытия для приложений маршрутов поддерживаются только во время разработки через рабочий процесс запуска Xcode. (Вы можете указать файл покрытия для заданной схемы запуска, используя панель «Параметры» в разделе «Запуск» редактора схем.) Приложения, которые архивированы и распространены (вне App Store) на устройства, не будут иметь доступа к файлам покрытия приложения.
  • ИСПРАВЛЕНО: Карты не приближаются к текущему местоположению при запуске из стороннего приложения.

Newsstand

  • ИСПРАВЛЕНО: Только простые HTTP-загрузки будут работать с Newsstand.

Passbook

  • Поле «Описание» теперь является обязательным полем для пропуска. Все пропуски, созданные без него, не пройдут проверку и не будут приняты.
  • Passbook в симуляторе больше не требует https/ssl при использовании webServiceURL при приеме пропуска.
  • ИСПРАВЛЕНО: Невозможно отобразить посадочные талоны на экране блокировки.
  • Пропуски больше не будут возвращаться к background.png, если strip.png не включен в ваш пакет пропуска.
  • Содержимое словаря userInfo для PKPassLibraryDidChangeNotification изменилось в случае удаленных пропусков. Пожалуйста, обратитесь к последней документации для нового словаря userInfo.

Безопасность

  • В iOS 5 подписывание сертификата с помощью MD5-подписи не поддерживается. Убедитесь, что сертификаты используют алгоритмы подписи на основе SHA1 или SHA2.
  • В iOS 6 улучшены средства конфиденциальности для Календаря, Напоминаний, Контактов и Фотографий.
    • Пользователи будут видеть диалоги доступа, когда приложение пытается получить доступ к любому из этих типов данных. Пользователь может включать и выключать доступ в «Настройки» > «Конфиденциальность».
    • Разработчики могут установить строку «цель» для каждого класса изолированных данных. iOS отображает эту строку пользователям, чтобы помочь им понять, почему их данные запрашиваются. Эти строки можно добавить с помощью редактора проектов Xcode, который находится на вкладке «Информация». Соответствующие имена ключей начинаются со строки «Privacy -«.
    • Внесены изменения во фреймворки Event Kit и Address Book, чтобы помочь разработчикам с этой функцией.

Симулятор

  • ИСПРАВЛЕНО: Панель подтверждения удаления приложения в симуляторе iOS долго отображается.
  • В симуляторе iOS не отображаются предупреждения о конфиденциальности для приложений, которые получают доступ к Фотографиям, Контактам, Календарю и Напоминаниям.
  • Загрузка контента, размещенного через In-App Purchase, в симуляторе iOS не поддерживается.
  • При попытке воспроизвести MP3-звук в симуляторе вместо этого вы услышите щелчок.

Общий фотопоток

  • Пользователи должны перейти в «Настройки» > «iCloud», чтобы убедиться, что они получают уведомления Общего фотопотока.
  • Чтобы поделиться фотопотоком с iOS 6 beta, вы должны пригласить кого-то, используя его адрес электронной почты iCloud; в противном случае он не получит приглашение.
  • Обновление с iOS 6 beta 1 до beta 2 приведет к повторной загрузке всех ваших Общих фотопотоков на устройстве.
  • Функция «Общий фотопоток» установлена в «ВЫКЛ.» при обновлении с iOS 6 beta 1 до более поздней версии. Настройка по умолчанию должна быть «ВКЛ.».
  • ИСПРАВЛЕНО: Отключение Общего фотопотока может привести к неотзывчивости Камеры; принудительное завершение работы приложения «Камера» решит эту проблему.

Социальные сети

  • Weibo отображается в приложении «Настройки» только при включенной китайской клавиатуре.
  • Метод requestAccessToAccountsWithType:withCompletionHandler: из ACAccountStore теперь устарел. Для доступа к учетным записям пользователей используйте метод requestAccessToAccountsWithType:options:completion:. В параметре *options* этого нового метода передайте nil для доступа к учетным записям Twitter и Weibo. Для доступа к учетным записям Facebook передайте словарь со следующими ключами (которые документированы в ACAccountStore.h):

    Вы больше не должны добавлять этот словарь в файл Info.plist вашего приложения, как это требовалось в beta 1.

  • При запросе доступа к учетным записям Facebook единственным необходимым ключом в вашем словаре параметров является ACFacebookAppIdKey. ACFacebookPermissionGroupKey и ACFacebookAppVersionKey теперь устарели. Если вы запрашиваете разрешение на запись в соответствии с ACFacebookPermissionsKey — например, publish_stream — вы должны предоставить значение для ACFacebookAudienceKey, которое может быть одним из ACFacebookAudienceEveryone, ACFacebookAudienceFriends или ACFacebookAudienceOnlyMe.

Строка состояния

  • Теперь можно задать параметры оттенка строки состояния в файле Info.plist вашего приложения. Вы можете сделать это, чтобы гарантировать, что цвет строки состояния соответствует цвету навигационной панели вашего приложения во время запуска. Чтобы установить оттенок строки состояния, добавьте ключ UIStatusBarTintParameters в файл Info.plist вашего приложения. Значение этого ключа — это словарь с соответствующими значениями, описывающими навигационную панель, которую ваше приложение имеет при запуске. Внутри словаря должен быть ключ UINavigationBar, значением которого также является словарь. Этот словарь содержит стиль начальной навигационной панели (с ключом Style) и является ли она полупрозрачной (с ключом Translucent). Если ваша навигационная панель их использует, вы также можете указать ее цвет оттенка (с ключом TintColor) или имя ее пользовательского фонового изображения (с ключом BackgroundImage).

UIKit

  • В iOS 5.1 класс UISplitViewController принимает стиль слайдинга при представлении левого представления (ранее видели только в Mail). Этот стиль используется, когда представление инициируется либо существующим элементом панели навигации, предоставленным методами делегата, либо жестом смахивания внутри правого представления. Для получения такого поведения не требуется дополнительного принятия API, и все существующие API — включая API экземпляра UIPopoverController, предоставленного делегатом — будут продолжать работать как прежде. Если жест не может быть поддержан в вашем приложении, установка свойства presentsWithGesture вашего контроллера разделения на NO отключает жест. Однако отключение жеста не рекомендуется, поскольку его использование обеспечивает согласованный пользовательский опыт во всех приложениях.
  • ИСПРАВЛЕНО: В iOS 6 были внесены изменения, чтобы вам больше не нужно было устанавливать делегат и реализовывать метод для распознавателей жестов одиночным пальцем и одиночным касанием. Это позволяет им хорошо работать с объектами UIControl.
  • В iOS 6 и более поздних версиях класс UIWebView рисует свое содержимое асинхронно.
  • Автоповорот изменяется в iOS 6. В iOS 6 метод shouldAutorotateToInterfaceOrientation: из UIViewController устарел. Вместо него следует использовать методы supportedInterfaceOrientationsForWindow: и shouldAutorotate.
    • Больше ответственности переходит к приложению и его делегату. Теперь контейнеры iOS (например, UINavigationController) не обращаются к своим дочерним элементам, чтобы определить, должны ли они поворачиваться. По умолчанию поддерживаемые ориентации интерфейса приложения и контроллера представления устанавливаются в UIInterfaceOrientationMaskAll для iPad и UIInterfaceOrientationMaskAllButUpsideDown для iPhone.
    • Поддерживаемые ориентации интерфейса контроллера представления могут меняться со временем — даже поддерживаемые ориентации интерфейса приложения могут меняться со временем. Система запрашивает у самого верхнего полноэкранного контроллера представления (обычно корневого контроллера представления) поддерживаемые им ориентации интерфейса всякий раз, когда устройство поворачивается или когда контроллер представления представляется с полноэкранным модальным стилем представления. Более того, поддерживаемые ориентации извлекаются только в том случае, если этот контроллер представления возвращает YES из своего метода shouldAutorotate. Система пересекает поддерживаемые ориентации контроллера представления с поддерживаемыми ориентациями приложения (как определено в файле Info.plist или методом application:supportedInterfaceOrientationsForWindow: делегата приложения), чтобы определить, следует ли поворачивать.
    • Система определяет, поддерживается ли ориентация, путем пересечения значения, возвращаемого методом supportedInterfaceOrientationsForWindow: приложения, со значением, возвращаемым методом supportedInterfaceOrientations самого верхнего полноэкранного контроллера.
    • Метод setStatusBarOrientation:animated: не устарел напрямую. Однако теперь он работает только в том случае, если метод supportedInterfaceOrientations самого верхнего полноэкранного контроллера представления возвращает 0. Это возлагает ответственность за обеспечение согласованности ориентации строки состояния на вызывающую сторону.
    • Для совместимости контроллеры представлений, которые все еще реализуют метод shouldAutorotateToInterfaceOrientation:, не получают нового поведения автоповорота. (Другими словами, они не возвращаются к использованию приложения, делегата приложения или файла Info.plist для определения поддерживаемых ориентаций.) Вместо этого метод shouldAutorotateToInterfaceOrientation: используется для синтеза информации, которая была бы возвращена методом supportedInterfaceOrientations.
  • Методы willRotateToInterfaceOrientation:duration:, willAnimateRotationToInterfaceOrientation:duration: и didRotateFromInterfaceOrientation: больше не вызываются ни для одного контроллера представления, который выполняет полноэкранное представление поверх себя — например, путем вызова presentViewController:animated:completion:.
    • Вы должны убедиться, что ваши приложения не используют эти методы для управления компоновкой любых подпредставлений. Вместо этого они должны использовать метод viewWillLayoutSubviews контроллера представления и настраивать компоновку, используя прямоугольник границ представления.
  • В iOS 6 методы viewWillUnload и viewDidUnload из UIViewController теперь устарели. Если вы использовали эти методы для освобождения данных, используйте метод didReceiveMemoryWarning вместо этого. Вы также можете использовать этот метод для освобождения ссылок на представление контроллера представления, если оно не используется. Вам потребуется проверить, что представление не находится в окне, прежде чем делать это.
  • Не поддерживается установка значений для свойств shadowOffset или shadowColor объекта UILabel, если его свойство attributedText содержит допустимую строку с атрибутами. Вместо этого используйте атрибут NSShadowAttributeName строки с атрибутами для установки тени.
  • Из-за проблем совместимости атрибут NSBaselineOffsetAttributeName больше не поддерживается в iOS 6.
  • Значение NSTextAlignmentNatural не поддерживается и вызовет исключение при использовании с свойством textAlignment из UILabel или при передаче в качестве параметра выравнивания методу drawInRect:withFont:lineBreakMode:alignment: из NSString.
  • Метод setContentStretch: из UIView устарел в этой бета-версии. Чтобы добиться того же эффекта, используйте метод resizableImageWithCapInsets: из UIImage и отображайте изображение с UIImageView.
  • Метод resizableImageWithCapInsets: из UIImage фактически изменяет размер изображений, разбивая их на плитки. В качестве оптимизации производительности он использует растягивание вместо мозаичного, когда пользователь не заметит разницы, например, когда растягивается один столбец или строка. Но в определенных обстоятельствах пользователь может захотеть фактически растянуть некоторую область изображения. В iOS 6 метод resizableImageWithCapInsets:resizingMode: позволяет вызывающей стороне указывать режим изменения размера — мозаичный или растягивающий.
  • Класс UICollectionViewLayout изменился:
    • Класс теперь поддерживает настройку анимаций, создаваемых во время вращения. Названия методов для настройки анимаций вставки и удаления также изменились, поэтому одни и те же «крючки» могут использоваться для вращения, а также для вставок и удалений.
    • Класс изменил некоторые названия методов. В частности, декоративные представления больше не именуются по «идентификатору повторного использования», а по «виду элемента». Приложения, использующие декоративные представления, должны будут изменить свой код и пересобрать его, чтобы учесть это.
  • Нижняя граница представления UILabel теперь отличается от его базовой линии. Ранее автоматическое размещение интерпретировало нижнюю часть UILabel как ту же, что и его базовую линию. Хотя это было удобно во многих случаях, это вызывало проблемы, если вы хотели поместить верхний край одной метки у нижнего края другой. В таком сценарии нижняя метка перекрывала верхнюю, а нисходящие элементы верхней метки могли сталкиваться с восходящими элементами нижней метки. Теперь автоматическое размещение интерпретирует UILayoutAttributeBottom как нижнюю часть текстового поля (предполагая, что метка не больше своего собственного размера контента) и UILayoutAttributeBaseline как базовую линию текста. Если вы уже создали код для размещения меток по нижнему или центральному элементу, ваш текст немного сместится, и вам нужно будет скорректировать ограничения.
  • Приложения с табличными представлениями в своих файлах nib или storyboard, созданные с использованием предыдущих версий iOS 6 beta, потребуют чистой сборки с beta 3 и новее.
  • Вот несколько заметок относительно поддержки автоматического размещения для UIScrollView:
    • В целом, автоматическое размещение считает верхний, левый, нижний и правый края представления *видимыми* краями. То есть, если вы привязываете представление к левому краю его суперпредставления, вы на самом деле привязываете его к минимальному значению x границ суперпредставления. Изменение происхождения границ суперпредставления *не* изменяет положение представления.
    • Класс UIScrollView прокручивает свое содержимое, изменяя происхождение своих границ. Чтобы это работало с автоматическим размещением, значение верхнего, левого, нижнего и правого краев *внутри* прокручиваемого представления теперь означает края его содержимого.
    • Ограничения для подпредставлений прокручиваемого представления должны приводить к размеру, заполняющему его, который затем интерпретируется как размер содержимого прокручиваемого представления. (Это не следует путать с методом intrinsicContentSize, используемым для автоматического размещения.) Для определения размера frame прокручиваемого представления с помощью автоматического размещения, ограничения должны либо явно указывать ширину и высоту прокручиваемого представления, либо края прокручиваемого представления должны быть привязаны к представлениям *вне* его поддерева.
    • Обратите внимание, что вы можете сделать подпредставление прокручиваемого представления «плавающим» (не прокручивающимся) над другим содержимым прокрутки, создавая ограничения между представлением и представлением вне поддерева прокручиваемого представления, например, между суперпредставлением прокручиваемого представления.
    • Вот несколько примеров настройки прокручиваемого представления:
      • Смешанный подход:
        1. Разместите и задайте размер вашего прокручиваемого представления с помощью ограничений, внешних по отношению к прокручиваемому представлению — то есть свойство translatesAutoresizingMaskIntoConstraints установлено в NO.
        2. Создайте простое представление содержимого UIView для вашего прокручиваемого представления, которое будет иметь нужный вам размер содержимого. Сделайте его подпредставлением прокручиваемого представления, но позвольте ему продолжать преобразовывать маску авторазмера в ограничения:
          UIView *contentView = [[UIView alloc]
              initWithFrame:CGRectMake(0,0,contentWidth,contentHeight)];
          [scrollView addSubview:contentView];
          // DON'T change contentView's translatesAutoresizingMaskIntoConstraints,
          // which defaults to YES;
        3. Установите размер содержимого прокручиваемого представления, чтобы он соответствовал размеру представления содержимого:
          [scrollView setContentSize:CGMakeSize(contentWidth,contentHeight)];
        4. Создайте представления, которые вы хотите поместить внутрь представления содержимого, и настройте их ограничения, чтобы расположить их внутри представления содержимого. В качестве альтернативы вы можете создать поддерево представлений для размещения в прокручиваемом представлении, настроить ограничения и вызвать метод systemLayoutSizeFittingSize: (с опцией UILayoutFittingCompressedSize), чтобы найти размер, который вы хотите использовать для представления содержимого, и свойство contentSize прокручиваемого представления.
      • Чистый подход автоматического размещения:
        1. В этом случае translatesAutoresizingMaskIntoConstraints должно быть установлено в NO для всех задействованных представлений.
        2. Разместите и задайте размер вашего прокручиваемого представления с помощью ограничений, внешних по отношению к прокручиваемому представлению.
        3. Используйте ограничения для размещения подпредставлений внутри прокручиваемого представления, убедившись, что ограничения привязаны ко всем четырем краям прокручиваемого представления и не полагаются на прокручиваемое представление для получения своего размера. Простым примером может быть большое представление изображения, которое имеет собственный размер содержимого, полученный из размера изображения. В методе viewDidLoad вашего контроллера представления вы должны включить следующий код:
          UIScrollView *scrollView = [[UIScrollView alloc] init];
          UIImageView *imageView = [[UIImageView alloc] init];
          [imageView setImage:[UIImage imageNamed:"MyReallyBigImage"]];
          [self.view addSubview:scrollView];
          [scrollView addSubview:imageView];
          scrollView.translatesAutoresizingMaskIntoConstraints = NO;
          imageView.translatesAutoresizingMaskIntoConstraints = NO;
          NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(scrollView,imageView);
          [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|" options:0 metrics: 0 viewsDictionary:viewsDictionary]];
          [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|" options:0 metrics: 0 viewsDictionary:viewsDictionary]];
          [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[imageView]|" options:0 metrics: 0 viewsDictionary:viewsDictionary]];
          [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[imageView]|" options:0 metrics: 0 viewsDictionary:viewsDictionary]];

          Это даст вам прокручиваемое представление, которое будет изменять размер по мере изменения размера представления контроллера представления (например, при повороте устройства), а представление изображения будет подпредставлением с прокруткой. Вам не нужно устанавливать размер содержимого прокручиваемого представления.

  • Учитывая следующую иерархию представлений:
    ContainerView
        |     OddHeightView
        |        |    EvenHeightView
        |    OtherFixedHeightView

    и эти ограничения:

    EvenHeightView.centerY == OddHeightView.centerY
    EvenHeightView.bottom (or baseline) ==  OtherFixedHeightView.bottom (or baseline)
    OtherFixedHeightView.top == ContainerView.top + 

    В iOS 6 beta 4 на устройствах без дисплея Retina, нижние (или базовые линии) EvenHeightView и OtherFixedHeightView были сдвинуты на один пиксель, и разработчик ничего не мог с этим поделать. Эта проблема теперь исправлена.

    • До изменений движок компоновки не целочисленно обрабатывал переменные положения для представлений, и эти ограничения всегда были выполнимы:
      ContainerView
          |    OddWidthView
          |    EvenWidthView
      OddWidthView.centerX == ContainerView.centerX
      EvenWidthView.centerX == ContainerView.centerX
      EvenWidthView.centerX == OddWidthView.centerX

      Теперь движок компоновки целочисленно обрабатывает переменные положения (x и y), а также переменные размеров (ширина и высота). Это означает, что он попытается удовлетворить три ограничения с *целочисленным* решением, которое может быть невозможно, и поэтому сообщит, что эти ограничения не могут быть удовлетворены. В этом случае, и во всех аналогичных случаях, разработчикам просто нужно удалить избыточное ограничение (или ограничения). В приведенном выше примере удаление любого из трех ограничений решит проблему.

  • В iOS 6 beta 4 существует известная ошибка: когда у вас есть ограничение с одним элементом, которым является прокручиваемое представление, другим элементом является потомок этого прокручиваемого представления, и вы добавляете ограничение к *предоку* этого прокручиваемого представления, то ограничение может перестать работать должным образом. Обходное решение заключается в добавлении таких ограничений только к самому прокручиваемому представлению, а не к какому-либо старому предку.

Safari и WebKit

  • WebKit на iOS теперь поддерживает методы requestAnimationFrame и cancelAnimationFrame в JavaScript, как описано здесь: http://www.w3.org/TR/animation-timing/.
    • Обратите внимание, что поскольку спецификация все еще находится на стадии рабочего черновика, эти методы имеют префикс webkit, поэтому они являются window.webkitRequestAnimationFrame иwindow.webkitCancelAnimationFrame.
  • Квота кэша по умолчанию для приложений увеличена с 5 МБ до 25 МБ.
  • Порог субдискретизации JPEG увеличен с 2 МП (мегапикселей) до 5 МП на всем поддерживаемом оборудовании, за исключением iPhone 3GS и iPod touch (4-го поколения).
  • Добавлена поддержка тегов  в веб-формах. Пользователи могут загружать существующие фотографии и видео из своей медиатеки или делать снимки и записывать видео с помощью камеры. Ранее этот элемент формы всегда был отключен.
  • С Safari 6.0 на OS X разработчики теперь могут использовать Web Inspector (инструмент веб-разработки) с подключенными устройствами iOS и iOS Simulator. Разработчики могут использовать Web Inspector для отладки Safari и класса UIWebView в своих собственных приложениях, созданных и запущенных из Xcode. Это заменяет баннер Debug Console в Safari.
  • В iOS 6 и более поздних версиях веб-данные (SQL Web Storage и LocalStorage) из объекта UIWebView могут храниться в каталоге, который будет резервироваться. Чтобы включить резервное копирование этих данных, установите ключ WebKitStoreWebDataForBackup в YES в пользовательских настройках вашего приложения. Это следует делать только в том случае, если ваше приложение полагается на данные веб-содержимого, которые не могут быть перезагружены. Если ваш объект UIWebView открывает ссылки на произвольное веб-содержимое, этот ключ следует установить в NO. Изменение значения этого ключа не сохранит существующие данные веб-представления.
  • В iOS 6 и более поздних версиях Safari больше не регистрируется для обычной схемы RSS/ATOM feed:. Приложениям, которые могут просматривать такие типы лент, рекомендуется зарегистрироваться для этой схемы URL.
  • WebKit больше не создает аппаратные ускоренные слои для элементов с опцией -webkit-transform: preserve-3d всегда. Авторы должны перестать использовать эту опцию как способ получения аппаратного ускорения.
  • Экспериментальная поддержка CSS3 Flexbox будет отключена. Пожалуйста, переключитесь с использования -webkit-flexbox и -webkit-inline-flexbox на -webkit-box и -webkit-inline-box.
  • Начиная с iOS 6, встроенные URL-адреса YouTube в форме http://www.youtube.com/watch?v=oHg5SJYRHA0 больше не будут работать. Эти URL-адреса предназначены для просмотра видео на сайте YouTube, а не для встраивания на веб-страницы. Вместо этого используемый формат описан здесь: https://developers.google.com/youtube/player_parameters.
  • В iOS 6 свойство keyboardDisplayRequiresUserAction было добавлено в класс UIWebView. По умолчанию свойство имеет значение YES, что означает, что вызов focus() для элемента формы не вызовет клавиатуру. Изменив свойство на NO, вызов JavaScript focus() для элемента формы сфокусирует элемент и автоматически вызовет клавиатуру.
  • Начиная с iOS 6, вызов focus() для элемента формы в веб-приложении сфокусирует элемент.