Add iOS Image File Format guidance and test app for run time analysis
This commit is contained in:
Родитель
5038396bf7
Коммит
ddf05e911b
|
@ -4,6 +4,7 @@ This guide contains best practices for building great experiences and writing su
|
|||
|
||||
## Table of Contents
|
||||
|
||||
* [iOS Image File Format](iOSImageFileFormat.md)
|
||||
* [Layout](Layout.md)
|
||||
* [Storyboards and Xibs](StoryboardsAndXibs.md)
|
||||
* [View Controllers](ViewControllers.md)
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
[[_TOC_]]
|
||||
# iOS Image File Format
|
||||
|
||||
Image assets officially support multiple file formats including PNG, PDF and SVG. The recommended image file format for iOS images is SVG images with "Preserve Vector Data" option disabled in Xcode. There's no significant difference in size or performance between PDF and SVG images when "Preserve Vector Data" option is disabled, but SVG images are easier share across all platforms.
|
||||
|
||||
## Vector based image file format Overview
|
||||
When a single scale PDF or SVG image with "Preserve Vector Data" option disabled is used for an imageset, Xcode generates corresponding @1x, @2x, or @3x PNG images depending on the build target at build time. At runtime, the application loads the PNG image from the app bundle, so the runtime behavior is the same as if PNG images are provided for the imageset.
|
||||
|
||||
When a single scale PDF or SVG image with "Preserve Vector Data" option enabled is used for an imageset, XCode adds the image vector data to the app bundle at build time. This option is useful if the image is expected to be stretched. At runtime, if the image is drawn at a different size from the intrinsic image size, the vector data will be used so that the image does not appear blurry.
|
||||
|
||||
Stretching an image is not supported or necessary in most scenarios such as displayed within a button; however, in the rare cases when an image needs to fill a variable size such as the entire screen, streching an image is indeed necessary.
|
||||
|
||||
## Bundle Size Impact
|
||||
When vector data is disabled, the bundle size difference between PDF and SVG graphics is very trivial. However, there is a significant application bundle size increase when "Preserve Vector Data" option is enabled; PDFs have a bigger size increase than SVGs. The following bundle sizes are collected by using the asset catalog compiling tool directly on generated PDF and SVG imagesets from [Fluent icons repo](https://github.com/microsoft/fluentui-system-icons). There are 7702 imagesets in total at the time of the size analysis.
|
||||
|
||||
| Image Type | Assets.car Size (no vector data preserved) | Assets.car Size (vector data preserved) | Delta |
|
||||
|--|--|--|--|
|
||||
| PDF | 6,384,824 bytes (6.4 MB on disk) | 45,495,136 bytes (45.5 MB on disk) | +39,110,312 bytes (~39 MB), +612% |
|
||||
| SVG | 6,386,488 bytes (6.4 MB on disk) | 18,037,888 bytes (18 MB on disk) | +11,651,400 bytes (~11 MB), +182% |
|
||||
|
||||
Note: the sizes above are built against a specific device type, so App Thinning is taken into account.
|
||||
|
||||
## Runtime Performance Impact
|
||||
There's no measurable runtime performance difference between "Preserve Vector Data" turned on and off when the image is drawn at intrinsic size. However, drawing an image with "Preserve Vector Data" enabled is much slower when the image is stretched; stretched SVG images have a slightly better performance than stretched PDF images. The following data is collected by time profiling drawing 1000 images all at the same time on screen.
|
||||
|
||||
| | PDF w/o vector data preserved | SVG w/o vector data preserved | PDF with vector data preserved | SVG with vector data preserved |
|
||||
|--|--|--|--|--|
|
||||
| Intrinsic Size | 233 | 233.6 | 235.3 | 233.3 |
|
||||
| Stretched | 101.3 | 102.6 | 433.3 | 402.7 |
|
||||
|
||||
### Methodology
|
||||
The time profiling was done on a physical device with Xcode Instruments' Time Profiler tool measuring the time it takes for `CA::Transaction::Commit()` to complete after initiating the drawing of 1000 images.
|
|
@ -0,0 +1,347 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 50;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
00577928240D96760033EEBB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 00E3682D22E12EF800E37F8E /* Assets.xcassets */; };
|
||||
00E3682722E12EF700E37F8E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00E3682622E12EF700E37F8E /* AppDelegate.swift */; };
|
||||
00E3682922E12EF700E37F8E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00E3682822E12EF700E37F8E /* ViewController.swift */; };
|
||||
00E3682C22E12EF700E37F8E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 00E3682A22E12EF700E37F8E /* Main.storyboard */; };
|
||||
00E3683122E12EF800E37F8E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 00E3682F22E12EF800E37F8E /* LaunchScreen.storyboard */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
00E3682322E12EF700E37F8E /* test.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = test.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
00E3682622E12EF700E37F8E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
00E3682822E12EF700E37F8E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
||||
00E3682B22E12EF700E37F8E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
00E3682D22E12EF800E37F8E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
00E3683022E12EF800E37F8E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
00E3683222E12EF800E37F8E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
00E3682022E12EF700E37F8E /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
00E3681A22E12EF700E37F8E = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00E3682522E12EF700E37F8E /* test */,
|
||||
00E3682422E12EF700E37F8E /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
00E3682422E12EF700E37F8E /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00E3682322E12EF700E37F8E /* test.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
00E3682522E12EF700E37F8E /* test */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00E3682622E12EF700E37F8E /* AppDelegate.swift */,
|
||||
00E3682822E12EF700E37F8E /* ViewController.swift */,
|
||||
00E3682A22E12EF700E37F8E /* Main.storyboard */,
|
||||
00E3682D22E12EF800E37F8E /* Assets.xcassets */,
|
||||
00E3682F22E12EF800E37F8E /* LaunchScreen.storyboard */,
|
||||
00E3683222E12EF800E37F8E /* Info.plist */,
|
||||
);
|
||||
path = test;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
00E3682222E12EF700E37F8E /* test */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 00E3683522E12EF800E37F8E /* Build configuration list for PBXNativeTarget "test" */;
|
||||
buildPhases = (
|
||||
00E3681F22E12EF700E37F8E /* Sources */,
|
||||
00E3682022E12EF700E37F8E /* Frameworks */,
|
||||
00E3682122E12EF700E37F8E /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = test;
|
||||
productName = test;
|
||||
productReference = 00E3682322E12EF700E37F8E /* test.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
00E3681B22E12EF700E37F8E /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1020;
|
||||
LastUpgradeCheck = 1220;
|
||||
ORGANIZATIONNAME = Microsoft;
|
||||
TargetAttributes = {
|
||||
00E3682222E12EF700E37F8E = {
|
||||
CreatedOnToolsVersion = 10.2.1;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 00E3681E22E12EF700E37F8E /* Build configuration list for PBXProject "test" */;
|
||||
compatibilityVersion = "Xcode 9.3";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 00E3681A22E12EF700E37F8E;
|
||||
productRefGroup = 00E3682422E12EF700E37F8E /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
00E3682222E12EF700E37F8E /* test */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
00E3682122E12EF700E37F8E /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
00577928240D96760033EEBB /* Assets.xcassets in Resources */,
|
||||
00E3683122E12EF800E37F8E /* LaunchScreen.storyboard in Resources */,
|
||||
00E3682C22E12EF700E37F8E /* Main.storyboard in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
00E3681F22E12EF700E37F8E /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
00E3682922E12EF700E37F8E /* ViewController.swift in Sources */,
|
||||
00E3682722E12EF700E37F8E /* AppDelegate.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
00E3682A22E12EF700E37F8E /* Main.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
00E3682B22E12EF700E37F8E /* Base */,
|
||||
);
|
||||
name = Main.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
00E3682F22E12EF800E37F8E /* LaunchScreen.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
00E3683022E12EF800E37F8E /* Base */,
|
||||
);
|
||||
name = LaunchScreen.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
00E3683322E12EF800E37F8E /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.2;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
00E3683422E12EF800E37F8E /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.2;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
00E3683622E12EF800E37F8E /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
DEVELOPMENT_ASSET_PATHS = test/Assets.xcassets;
|
||||
DEVELOPMENT_TEAM = UBF8T346G9;
|
||||
INFOPLIST_FILE = test/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = microsoft.test;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "iOS Team Provisioning Profile";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
00E3683722E12EF800E37F8E /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
DEVELOPMENT_ASSET_PATHS = test/Assets.xcassets;
|
||||
DEVELOPMENT_TEAM = UBF8T346G9;
|
||||
INFOPLIST_FILE = test/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = microsoft.test;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "iOS Team Provisioning Profile";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
00E3681E22E12EF700E37F8E /* Build configuration list for PBXProject "test" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
00E3683322E12EF800E37F8E /* Debug */,
|
||||
00E3683422E12EF800E37F8E /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
00E3683522E12EF800E37F8E /* Build configuration list for PBXNativeTarget "test" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
00E3683622E12EF800E37F8E /* Debug */,
|
||||
00E3683722E12EF800E37F8E /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 00E3681B22E12EF700E37F8E /* Project object */;
|
||||
}
|
7
testapps/iOSImageFormatProfilingTestApp/test.xcodeproj/project.xcworkspace/contents.xcworkspacedata
сгенерированный
Normal file
7
testapps/iOSImageFormatProfilingTestApp/test.xcodeproj/project.xcworkspace/contents.xcworkspacedata
сгенерированный
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:test.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
Двоичные данные
testapps/iOSImageFormatProfilingTestApp/test.xcodeproj/project.xcworkspace/xcuserdata/chenyang.xcuserdatad/UserInterfaceState.xcuserstate
сгенерированный
Normal file
Двоичные данные
testapps/iOSImageFormatProfilingTestApp/test.xcodeproj/project.xcworkspace/xcuserdata/chenyang.xcuserdatad/UserInterfaceState.xcuserstate
сгенерированный
Normal file
Двоичный файл не отображается.
Двоичные данные
testapps/iOSImageFormatProfilingTestApp/test.xcodeproj/project.xcworkspace/xcuserdata/mavitale.xcuserdatad/UserInterfaceState.xcuserstate
сгенерированный
Normal file
Двоичные данные
testapps/iOSImageFormatProfilingTestApp/test.xcodeproj/project.xcworkspace/xcuserdata/mavitale.xcuserdatad/UserInterfaceState.xcuserstate
сгенерированный
Normal file
Двоичный файл не отображается.
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Bucket
|
||||
uuid = "2F74C6B4-F951-4BEE-B626-B7046958F7F7"
|
||||
type = "0"
|
||||
version = "2.0">
|
||||
</Bucket>
|
Двоичные данные
testapps/iOSImageFormatProfilingTestApp/test.xcodeproj/project.xcworkspace/xcuserdata/yangche.xcuserdatad/UserInterfaceState.xcuserstate
сгенерированный
Normal file
Двоичные данные
testapps/iOSImageFormatProfilingTestApp/test.xcodeproj/project.xcworkspace/xcuserdata/yangche.xcuserdatad/UserInterfaceState.xcuserstate
сгенерированный
Normal file
Двоичный файл не отображается.
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Bucket
|
||||
uuid = "9CF5CDEF-147C-4C0B-88B7-311AD4190847"
|
||||
type = "0"
|
||||
version = "2.0">
|
||||
</Bucket>
|
|
@ -0,0 +1,78 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1220"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "00E3682222E12EF700E37F8E"
|
||||
BuildableName = "test.app"
|
||||
BlueprintName = "test"
|
||||
ReferencedContainer = "container:test.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Release"
|
||||
selectedDebuggerIdentifier = ""
|
||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "00E3682222E12EF700E37F8E"
|
||||
BuildableName = "test.app"
|
||||
BlueprintName = "test"
|
||||
ReferencedContainer = "container:test.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "00E3682222E12EF700E37F8E"
|
||||
BuildableName = "test.app"
|
||||
BlueprintName = "test"
|
||||
ReferencedContainer = "container:test.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Bucket
|
||||
uuid = "F5892F54-7E76-45FF-B8B3-AC8397E7A00C"
|
||||
type = "1"
|
||||
version = "2.0">
|
||||
</Bucket>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>test.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>00E3682222E12EF700E37F8E</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>test.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>test.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,42 @@
|
|||
//
|
||||
// Copyright © 2021 Microsoft. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
// Override point for customization after application launch.
|
||||
return true
|
||||
}
|
||||
|
||||
func applicationWillResignActive(_ application: UIApplication) {
|
||||
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
|
||||
}
|
||||
|
||||
func applicationDidEnterBackground(_ application: UIApplication) {
|
||||
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||
}
|
||||
|
||||
func applicationWillEnterForeground(_ application: UIApplication) {
|
||||
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
|
||||
}
|
||||
|
||||
func applicationDidBecomeActive(_ application: UIApplication) {
|
||||
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||
}
|
||||
|
||||
func applicationWillTerminate(_ application: UIApplication) {
|
||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "83.5x83.5",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ios-marketing",
|
||||
"size" : "1024x1024",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
12
testapps/iOSImageFormatProfilingTestApp/test/Assets.xcassets/Image.imageset/Contents.json
поставляемый
Normal file
12
testapps/iOSImageFormatProfilingTestApp/test/Assets.xcassets/Image.imageset/Contents.json
поставляемый
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Email.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
Двоичные данные
testapps/iOSImageFormatProfilingTestApp/test/Assets.xcassets/Image.imageset/Email.pdf
поставляемый
Normal file
Двоичные данные
testapps/iOSImageFormatProfilingTestApp/test/Assets.xcassets/Image.imageset/Email.pdf
поставляемый
Normal file
Двоичный файл не отображается.
15
testapps/iOSImageFormatProfilingTestApp/test/Assets.xcassets/ImageVector.imageset/Contents.json
поставляемый
Normal file
15
testapps/iOSImageFormatProfilingTestApp/test/Assets.xcassets/ImageVector.imageset/Contents.json
поставляемый
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Email.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"preserves-vector-representation" : true
|
||||
}
|
||||
}
|
Двоичные данные
testapps/iOSImageFormatProfilingTestApp/test/Assets.xcassets/ImageVector.imageset/Email.pdf
поставляемый
Normal file
Двоичные данные
testapps/iOSImageFormatProfilingTestApp/test/Assets.xcassets/ImageVector.imageset/Email.pdf
поставляемый
Normal file
Двоичный файл не отображается.
12
testapps/iOSImageFormatProfilingTestApp/test/Assets.xcassets/SVGImage.imageset/Contents.json
поставляемый
Normal file
12
testapps/iOSImageFormatProfilingTestApp/test/Assets.xcassets/SVGImage.imageset/Contents.json
поставляемый
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "ic_fluent_mail_24_regular.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
3
testapps/iOSImageFormatProfilingTestApp/test/Assets.xcassets/SVGImage.imageset/ic_fluent_mail_24_regular.svg
поставляемый
Normal file
3
testapps/iOSImageFormatProfilingTestApp/test/Assets.xcassets/SVGImage.imageset/ic_fluent_mail_24_regular.svg
поставляемый
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.25 4H18.75C20.483 4 21.8992 5.35645 21.9949 7.06558L22 7.25V16.75C22 18.483 20.6435 19.8992 18.9344 19.9949L18.75 20H5.25C3.51697 20 2.10075 18.6435 2.00514 16.9344L2 16.75V7.25C2 5.51697 3.35645 4.10075 5.06558 4.00514L5.25 4H18.75H5.25ZM20.5 9.373L12.3493 13.6637C12.1619 13.7623 11.9431 13.7764 11.7468 13.706L11.6507 13.6637L3.5 9.374V16.75C3.5 17.6682 4.20711 18.4212 5.10647 18.4942L5.25 18.5H18.75C19.6682 18.5 20.4212 17.7929 20.4942 16.8935L20.5 16.75V9.373ZM18.75 5.5H5.25C4.33183 5.5 3.57881 6.20711 3.5058 7.10647L3.5 7.25V7.679L12 12.1525L20.5 7.678V7.25C20.5 6.33183 19.7929 5.57881 18.8935 5.5058L18.75 5.5Z" fill="#212121"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 756 B |
15
testapps/iOSImageFormatProfilingTestApp/test/Assets.xcassets/SVGImageVector.imageset/Contents.json
поставляемый
Normal file
15
testapps/iOSImageFormatProfilingTestApp/test/Assets.xcassets/SVGImageVector.imageset/Contents.json
поставляемый
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "ic_fluent_mail_24_regular.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"preserves-vector-representation" : true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.25 4H18.75C20.483 4 21.8992 5.35645 21.9949 7.06558L22 7.25V16.75C22 18.483 20.6435 19.8992 18.9344 19.9949L18.75 20H5.25C3.51697 20 2.10075 18.6435 2.00514 16.9344L2 16.75V7.25C2 5.51697 3.35645 4.10075 5.06558 4.00514L5.25 4H18.75H5.25ZM20.5 9.373L12.3493 13.6637C12.1619 13.7623 11.9431 13.7764 11.7468 13.706L11.6507 13.6637L3.5 9.374V16.75C3.5 17.6682 4.20711 18.4212 5.10647 18.4942L5.25 18.5H18.75C19.6682 18.5 20.4212 17.7929 20.4942 16.8935L20.5 16.75V9.373ZM18.75 5.5H5.25C4.33183 5.5 3.57881 6.20711 3.5058 7.10647L3.5 7.25V7.679L12 12.1525L20.5 7.678V7.25C20.5 6.33183 19.7929 5.57881 18.8935 5.5058L18.75 5.5Z" fill="#212121"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 756 B |
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14868" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="52.173913043478265" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15510"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="test" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="139" y="86"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,126 @@
|
|||
//
|
||||
// Copyright © 2021 Microsoft. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class ResettableView: UIView {
|
||||
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
super.touchesEnded(touches, with: event)
|
||||
subviews.forEach { $0.removeFromSuperview() }
|
||||
setNeedsLayout()
|
||||
setNeedsDisplay()
|
||||
layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
class ViewController: UIViewController {
|
||||
|
||||
var imagesContainerView = ResettableView()
|
||||
let stretchingSwitch = UISwitch()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
let pngButton = UIButton(frame: .zero)
|
||||
pngButton.setTitle("Draw PNG Images", for: .normal)
|
||||
pngButton.addTarget(self, action: #selector(pressedPngImages(_:)), for: .touchUpInside)
|
||||
|
||||
let vectorButton = UIButton(frame: .zero)
|
||||
vectorButton.setTitle("Draw Vector Images", for: .normal)
|
||||
vectorButton.addTarget(self, action: #selector(pressedVectorImages(_:)), for: .touchUpInside)
|
||||
|
||||
let pngSVGButton = UIButton(frame: .zero)
|
||||
pngSVGButton.setTitle("Draw PNG SVG Images", for: .normal)
|
||||
pngSVGButton.addTarget(self, action: #selector(pressedSVGPngImages(_:)), for: .touchUpInside)
|
||||
|
||||
let vectorSVGButton = UIButton(frame: .zero)
|
||||
vectorSVGButton.setTitle("Draw Vector SVG Images", for: .normal)
|
||||
vectorSVGButton.addTarget(self, action: #selector(pressedSVGVectorImages(_:)), for: .touchUpInside)
|
||||
|
||||
let switchLabel = UILabel(frame: .zero)
|
||||
switchLabel.text = "Stretch Images"
|
||||
|
||||
let switchStackView = UIStackView(arrangedSubviews: [
|
||||
switchLabel,
|
||||
stretchingSwitch,
|
||||
])
|
||||
|
||||
let stackView = UIStackView(arrangedSubviews: [
|
||||
imagesContainerView,
|
||||
pngButton,
|
||||
vectorButton,
|
||||
pngSVGButton,
|
||||
vectorSVGButton,
|
||||
switchStackView,
|
||||
])
|
||||
|
||||
stackView.axis = .vertical
|
||||
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
view.addSubview(stackView)
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
view.centerXAnchor.constraint(equalTo: stackView.centerXAnchor),
|
||||
view.centerYAnchor.constraint(equalTo: stackView.centerYAnchor),
|
||||
])
|
||||
}
|
||||
|
||||
@objc func pressedPngImages(_ sender: Any) {
|
||||
let collection = imageViews(shouldStretch: stretchingSwitch.isOn, imageName: "Image")
|
||||
addCollectionToViewHierarchy(collection: collection) }
|
||||
|
||||
@objc func pressedVectorImages(_ sender: Any) {
|
||||
let collection = imageViews(shouldStretch: stretchingSwitch.isOn, imageName: "ImageVector")
|
||||
addCollectionToViewHierarchy(collection: collection)
|
||||
}
|
||||
|
||||
@objc func pressedSVGPngImages(_ sender: Any) {
|
||||
let collection = imageViews(shouldStretch: stretchingSwitch.isOn, imageName: "SVGImage")
|
||||
addCollectionToViewHierarchy(collection: collection) }
|
||||
|
||||
@objc func pressedSVGVectorImages(_ sender: Any) {
|
||||
let collection = imageViews(shouldStretch: stretchingSwitch.isOn, imageName: "SVGImageVector")
|
||||
addCollectionToViewHierarchy(collection: collection)
|
||||
}
|
||||
|
||||
func addCollectionToViewHierarchy(collection: UIView) {
|
||||
collection.translatesAutoresizingMaskIntoConstraints = false
|
||||
imagesContainerView.addSubview(collection)
|
||||
NSLayoutConstraint.activate([
|
||||
collection.leadingAnchor.constraint(equalTo: imagesContainerView.leadingAnchor),
|
||||
collection.trailingAnchor.constraint(equalTo: imagesContainerView.trailingAnchor),
|
||||
collection.topAnchor.constraint(equalTo: imagesContainerView.topAnchor),
|
||||
collection.bottomAnchor.constraint(equalTo: imagesContainerView.bottomAnchor),
|
||||
])
|
||||
}
|
||||
|
||||
func imageViews(shouldStretch: Bool, imageName: String) -> UIView {
|
||||
var rowStack: [UIStackView] = []
|
||||
for _ in 0...numberOfRows {
|
||||
var images: [UIImageView] = []
|
||||
for _ in 0...numberOfColumns {
|
||||
let imageView = UIImageView.init(image:UIImage.init(named:imageName))
|
||||
if (shouldStretch) {
|
||||
NSLayoutConstraint.activate([
|
||||
imageView.widthAnchor.constraint(equalToConstant: 135),
|
||||
imageView.heightAnchor.constraint(equalToConstant: 131),
|
||||
])
|
||||
}
|
||||
images.append(imageView)
|
||||
}
|
||||
let columnStack = UIStackView(arrangedSubviews: images)
|
||||
columnStack.axis = .vertical
|
||||
rowStack.append(UIStackView(arrangedSubviews: images))
|
||||
}
|
||||
|
||||
let collection = UIStackView(arrangedSubviews: rowStack)
|
||||
collection.axis = .vertical
|
||||
|
||||
return collection
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate let numberOfRows = 40
|
||||
fileprivate let numberOfColumns = 25
|
Загрузка…
Ссылка в новой задаче