| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580 |
- //
- // ZLPhotoConfiguration.swift
- // ZLPhotoBrowser
- //
- // Created by long on 2020/8/11.
- //
- // Copyright (c) 2020 Long Zhang <495181165@qq.com>
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- // THE SOFTWARE.
- import UIKit
- import Photos
- public typealias Second = Int
- public class ZLPhotoConfiguration: NSObject {
- private static var single = ZLPhotoConfiguration()
-
- @objc public class func `default`() -> ZLPhotoConfiguration {
- return ZLPhotoConfiguration.single
- }
-
- @objc public class func resetConfiguration() {
- ZLPhotoConfiguration.single = ZLPhotoConfiguration()
- }
-
- /// Framework style.
- @objc public var style: ZLPhotoBrowserStyle = .embedAlbumList
-
- @objc public var statusBarStyle: UIStatusBarStyle = .lightContent
-
- /// Photo sorting method, the preview interface is not affected by this parameter. Defaults to true.
- @objc public var sortAscending = true
-
- private var pri_maxSelectCount = 9
- /// Anything superior than 1 will enable the multiple selection feature. Defaults to 9.
- @objc public var maxSelectCount: Int {
- set {
- pri_maxSelectCount = max(1, newValue)
- }
- get {
- return pri_maxSelectCount
- }
- }
-
- private var pri_maxVideoSelectCount = 0
- /// A count for video max selection. Defaults to 0.
- /// - warning: Only valid in mix selection mode. (i.e. allowMixSelect = true)
- @objc public var maxVideoSelectCount: Int {
- set {
- pri_maxVideoSelectCount = newValue
- }
- get {
- if pri_maxVideoSelectCount <= 0 {
- return maxSelectCount
- } else {
- return max(minVideoSelectCount, min(pri_maxVideoSelectCount, maxSelectCount))
- }
- }
- }
-
- private var pri_minVideoSelectCount = 0
- /// A count for video min selection. Defaults to 0.
- /// - warning: Only valid in mix selection mode. (i.e. allowMixSelect = true)
- @objc public var minVideoSelectCount: Int {
- set {
- pri_minVideoSelectCount = newValue
- }
- get {
- return min(maxSelectCount, max(pri_minVideoSelectCount, 0))
- }
- }
-
- /// Whether photos and videos can be selected together. Default is true.
- /// If set to false, only one video can be selected. Defaults to true.
- @objc public var allowMixSelect = true
-
- /// Preview selection max preview count, if the value is zero, only show `Camera`, `Album`, `Cancel` buttons. Defaults to 20.
- @objc public var maxPreviewCount = 20
-
- @objc public var cellCornerRadio: CGFloat = 0
-
- /// If set to false, gif and livephoto cannot be selected either. Defaults to true.
- @objc public var allowSelectImage = true
-
- @objc public var allowSelectVideo = true
-
- /// Allow select Gif, it only controls whether it is displayed in Gif form.
- /// If value is false, the Gif logo is not displayed. Defaults to true.
- @objc public var allowSelectGif = true
-
- /// Allow select LivePhoto, it only controls whether it is displayed in LivePhoto form.
- /// If value is false, the LivePhoto logo is not displayed. Defaults to false.
- @objc public var allowSelectLivePhoto = false
-
- private var pri_allowTakePhotoInLibrary = true
- /// Allow take photos in the album. Defaults to true.
- /// - warning: If allowTakePhoto and allowRecordVideo are both false, it will not be displayed.
- @objc public var allowTakePhotoInLibrary: Bool {
- set {
- pri_allowTakePhotoInLibrary = newValue
- }
- get {
- return pri_allowTakePhotoInLibrary && (allowTakePhoto || allowRecordVideo)
- }
- }
-
- @objc public var allowEditImage = true
-
- /// - warning: The video can only be edited when no photos are selected, or only one video is selected, and the selection callback is executed immediately after editing is completed.
- @objc public var allowEditVideo = false
-
- /// Animation duration for select button
- @objc public var selectBtnAnimationDuration: CFTimeInterval = 0.4
-
- /// After selecting a image/video in the thumbnail interface, enter the editing interface directly. Defaults to false.
- /// - discussion: Editing image is only valid when allowEditImage is true and maxSelectCount is 1.
- /// Editing video is only valid when allowEditVideo is true and maxSelectCount is 1.
- @objc public var editAfterSelectThumbnailImage = false
-
- /// Only valid when allowMixSelect is false and allowEditVideo is true. Defaults to true.
- /// Just like the Wechat-Timeline selection style. If you want to crop the video after select thumbnail under allowMixSelect = true, please use **editAfterSelectThumbnailImage**.
- @objc public var cropVideoAfterSelectThumbnail = true
-
- /// If image edit tools only has clip and this property is true. When you click edit, the cropping interface (i.e. ZLClipImageViewController) will be displayed. Defaults to false.
- @objc public var showClipDirectlyIfOnlyHasClipTool = false
-
- /// Save the edited image to the album after editing. Defaults to true.
- @objc public var saveNewImageAfterEdit = true
-
- /// If true, you can slide select photos in album. Defaults to true.
- @objc public var allowSlideSelect = true
-
- /// When slide select is active, will auto scroll to top or bottom when your finger at the top or bottom. Defaults to true.
- @objc public var autoScrollWhenSlideSelectIsActive = true
-
- /// The max speed (pt/s) of auto scroll. Defaults to 600.
- @objc public var autoScrollMaxSpeed: CGFloat = 600
-
- /// If true, you can drag select photo when preview selection style. Defaults to false.
- @objc public var allowDragSelect = false
-
- /// Allow select full image. Defaults to true.
- @objc public var allowSelectOriginal = true
-
- /// Allow access to the preview large image interface (That is, whether to allow access to the large image interface after clicking the thumbnail image). Defaults to true.
- @objc public var allowPreviewPhotos = true
-
- /// Whether to show the status bar when previewing photos. Defaults to false.
- @objc public var showStatusBarInPreviewInterface = false
-
- /// Whether to show the preview button (i.e. the preview button in the lower left corner of the thumbnail interface). Defaults to true.
- @objc public var showPreviewButtonInAlbum = true
-
- private var pri_columnCount: Int = 4
- /// The column count when iPhone is in portait mode. Minimum is 2, maximum is 6. Defaults to 4.
- /// ```
- /// iPhone landscape mode: columnCount += 2.
- /// iPad portait mode: columnCount += 2.
- /// iPad landscape mode: columnCount += 4.
- /// ```
- @objc public var columnCount: Int {
- set {
- pri_columnCount = min(6, max(newValue, 2))
- }
- get {
- return pri_columnCount
- }
- }
-
- /// Maximum cropping time when editing video, unit: second. Defaults to 10.
- @objc public var maxEditVideoTime: Second = 10
-
- /// Allow to choose the maximum duration of the video. Defaults to 120.
- @objc public var maxSelectVideoDuration: Second = 120
-
- /// Allow to choose the minimum duration of the video. Defaults to 0.
- @objc public var minSelectVideoDuration: Second = 0
-
- private var pri_editImageTools: [ZLEditImageViewController.EditImageTool] = [.draw, .clip, .imageSticker, .textSticker, .mosaic, .filter]
- /// Edit image tools. (Default order is draw, clip, imageSticker, textSticker, mosaic, filtter)
- /// Because Objective-C Array can't contain Enum styles, so this property is invalid in Objective-C.
- /// - warning: If you want to use the image sticker feature, you must provide a view that implements ZLImageStickerContainerDelegate.
- public var editImageTools: [ZLEditImageViewController.EditImageTool] {
- set {
- pri_editImageTools = newValue
- }
- get {
- if pri_editImageTools.isEmpty {
- return [.draw, .clip, .imageSticker, .textSticker, .mosaic, .filter]
- } else {
- return pri_editImageTools
- }
- }
- }
-
- private var pri_editImageDrawColors: [UIColor] = [.white, .black, zlRGB(241, 79, 79), zlRGB(243, 170, 78), zlRGB(80, 169, 56), zlRGB(30, 183, 243), zlRGB(139, 105, 234)]
- /// Draw colors for image editor.
- @objc public var editImageDrawColors: [UIColor] {
- set {
- pri_editImageDrawColors = newValue
- }
- get {
- if pri_editImageDrawColors.isEmpty {
- return [.white, .black, zlRGB(241, 79, 79), zlRGB(243, 170, 78), zlRGB(80, 169, 56), zlRGB(30, 183, 243), zlRGB(139, 105, 234)]
- } else {
- return pri_editImageDrawColors
- }
- }
- }
-
- /// The default draw color. If this color not in editImageDrawColors, will pick the first color in editImageDrawColors as the default.
- @objc public var editImageDefaultDrawColor = zlRGB(241, 79, 79)
-
- private var pri_editImageClipRatios: [ZLImageClipRatio] = [.custom]
- /// Edit ratios for image editor.
- @objc public var editImageClipRatios: [ZLImageClipRatio] {
- set {
- pri_editImageClipRatios = newValue
- }
- get {
- if pri_editImageClipRatios.isEmpty {
- return [.custom]
- } else {
- return pri_editImageClipRatios
- }
- }
- }
-
- private var pri_textStickerTextColors: [UIColor] = [.white, .black, zlRGB(241, 79, 79), zlRGB(243, 170, 78), zlRGB(80, 169, 56), zlRGB(30, 183, 243), zlRGB(139, 105, 234)]
- /// Text sticker colors for image editor.
- @objc public var textStickerTextColors: [UIColor] {
- set {
- pri_textStickerTextColors = newValue
- }
- get {
- if pri_textStickerTextColors.isEmpty {
- return [.white, .black, zlRGB(241, 79, 79), zlRGB(243, 170, 78), zlRGB(80, 169, 56), zlRGB(30, 183, 243), zlRGB(139, 105, 234)]
- } else {
- return pri_textStickerTextColors
- }
- }
- }
-
- /// The default text sticker color. If this color not in textStickerTextColors, will pick the first color in textStickerTextColors as the default.
- @objc public var textStickerDefaultTextColor = UIColor.white
-
- private var pri_filters: [ZLFilter] = ZLFilter.all
- /// Filters for image editor.
- @objc public var filters: [ZLFilter] {
- set {
- pri_filters = newValue
- }
- get {
- if pri_filters.isEmpty {
- return ZLFilter.all
- } else {
- return pri_filters
- }
- }
- }
-
- @objc public var imageStickerContainerView: (UIView & ZLImageStickerContainerDelegate)? = nil
-
- /// Show the image captured by the camera is displayed on the camera button inside the album. Defaults to false.
- @objc public var showCaptureImageOnTakePhotoBtn = false
-
- /// In single selection mode, whether to display the selection button. Defaults to false.
- @objc public var showSelectBtnWhenSingleSelect = false
-
- /// Overlay a mask layer on top of the selected photos. Defaults to true.
- @objc public var showSelectedMask = true
-
- /// Display a border on the selected photos cell. Defaults to false.
- @objc public var showSelectedBorder = false
-
- /// Overlay a mask layer above the cells that cannot be selected. Defaults to true.
- @objc public var showInvalidMask = true
-
- /// Display the index of the selected photos. Defaults to true.
- @objc public var showSelectedIndex = true
-
- /// Display the selected photos at the bottom of the preview large photos interface. Defaults to true.
- @objc public var showSelectedPhotoPreview = true
-
- /// Developers can customize images, but the name of the custom image resource must be consistent with the image name in the replaced bundle.
- /// - example: Developers need to replace the selected and unselected image resources, and the array that needs to be passed in is
- /// ["zl_btn_selected", "zl_btn_unselected"].
- @objc public var customImageNames: [String] = [] {
- didSet {
- ZLCustomImageDeploy.deploy = self.customImageNames
- }
- }
-
- /// Allow framework fetch photos when callback. Defaults to true.
- @objc public var shouldAnialysisAsset = true
-
- /// Timeout for image parsing. Defaults to 20.
- @objc public var timeout: TimeInterval = 20
-
- /// Language for framework.
- @objc public var languageType: ZLLanguageType = .system {
- didSet {
- ZLCustomLanguageDeploy.language = self.languageType
- Bundle.resetLanguage()
- }
- }
-
- /// Developers can customize languages (This property is only for objc).
- /// - example: If you needs to replace
- /// key: @"loading", value: @"loading, waiting please" language,
- /// The dictionary that needs to be passed in is @[@"loading": @"text to be replaced"].
- /// - warning: Please pay attention to the placeholders contained in languages when changing, such as %ld, %@.
- @objc public var customLanguageKeyValue_objc: [String: String] = [:] {
- didSet {
- var swiftParams: [ZLLocalLanguageKey: String] = [:]
- customLanguageKeyValue_objc.forEach { (key, value) in
- swiftParams[ZLLocalLanguageKey(rawValue: key)] = value
- }
- self.customLanguageKeyValue = swiftParams
- }
- }
-
- /// Developers can customize languages.
- /// - example: If you needs to replace
- /// key: .loading, value: "loading, waiting please" language,
- /// The dictionary that needs to be passed in is [.loading: "text to be replaced"].
- /// - warning: Please pay attention to the placeholders contained in languages when changing, such as %ld, %@.
- public var customLanguageKeyValue: [ZLLocalLanguageKey: String] = [:] {
- didSet {
- ZLCustomLanguageDeploy.deploy = self.customLanguageKeyValue
- }
- }
-
- /// Whether to use custom camera. Defaults to true.
- @objc public var useCustomCamera = true
-
- private var pri_allowTakePhoto = true
- /// Allow taking photos in the camera (Need allowSelectImage to be true). Defaults to true.
- @objc public var allowTakePhoto: Bool {
- set {
- pri_allowTakePhoto = newValue
- }
- get {
- return pri_allowTakePhoto && allowSelectImage
- }
- }
-
- private var pri_allowRecordVideo = true
- /// Allow recording in the camera (Need allowSelectVideo to be true). Defaults to true.
- @objc public var allowRecordVideo: Bool {
- set {
- pri_allowRecordVideo = newValue
- }
- get {
- return pri_allowRecordVideo && allowSelectVideo
- }
- }
-
- private var pri_minRecordDuration: Second = 0
- /// Minimum recording duration. Defaults to 0.
- @objc public var minRecordDuration: Second {
- set {
- pri_minRecordDuration = max(0, newValue)
- }
- get {
- return pri_minRecordDuration
- }
- }
-
- private var pri_maxRecordDuration: Second = 10
- /// Maximum recording duration. Defaults to 10, minimum is 1.
- @objc public var maxRecordDuration: Second {
- set {
- pri_maxRecordDuration = max(1, newValue)
- }
- get {
- return pri_maxRecordDuration
- }
- }
-
- /// Video resolution. Defaults to hd1280x720.
- @objc public var sessionPreset: ZLCustomCamera.CaptureSessionPreset = .hd1280x720
-
- /// Video export format for recording video and editing video. Defaults to mov.
- @objc public var videoExportType: ZLCustomCamera.VideoExportType = .mov
-
- /// Camera flahs mode. Default is off. Defaults to off.
- @objc public var cameraFlashMode: ZLCustomCamera.CameraFlashMode = .off
-
- /// Hud style. Defaults to lightBlur.
- @objc public var hudStyle: ZLProgressHUD.HUDStyle = .lightBlur
-
- /// Navigation bar blur effect.
- @objc public var navViewBlurEffect: UIBlurEffect? = UIBlurEffect(style: .dark)
-
- /// Bottom too bar blur effect.
- @objc public var bottomToolViewBlurEffect: UIBlurEffect? = UIBlurEffect(style: .dark)
-
- /// Color configuration for framework.
- @objc public var themeColorDeploy: ZLPhotoThemeColorDeploy = .default()
-
- /// Font name.
- @objc public var themeFontName: String? = nil {
- didSet {
- ZLCustomFontDeploy.fontName = self.themeFontName
- }
- }
-
- /// This block will be called before selecting an image, the developer can first determine whether the asset is allowed to be selected.
- /// Only control whether it is allowed to be selected, and will not affect the selection logic in the framework.
- /// - Tips: If the choice is not allowed, the developer can toast prompt the user for relevant information.
- @objc public var canSelectAsset: ( (PHAsset) -> Bool )?
-
- /// If user choose limited Photo mode, a button with '+' will be added to the ZLThumbnailViewController. It will call PHPhotoLibrary.shared().presentLimitedLibraryPicker(from:) to add photo. Defaults to true.
- /// E.g., Sina Weibo's ImagePicker
- @objc public var showAddPhotoButton: Bool = true
-
- /// iOS14 limited Photo mode, will show collection footer view in ZLThumbnailViewController.
- /// Will go to system setting if clicked. Defaults to true.
- @objc public var showEnterSettingTips = true
-
- /// Callback after the no authority alert dismiss.
- @objc public var noAuthorityCallback: ( (ZLNoAuthorityType) -> Void )?
-
- }
- @objc public enum ZLNoAuthorityType: Int {
- case library
- case camera
- case microphone
- }
- @objc public enum ZLPhotoBrowserStyle: Int {
-
- /// The album list is embedded in the navigation of the thumbnail interface, click the drop-down display.
- case embedAlbumList
-
- /// The display relationship between the album list and the thumbnail interface is push.
- case externalAlbumList
-
- }
- /// Color deploy
- public class ZLPhotoThemeColorDeploy: NSObject {
-
- @objc public class func `default`() -> ZLPhotoThemeColorDeploy {
- return ZLPhotoThemeColorDeploy()
- }
-
- /// Preview selection mode, transparent background color above.
- @objc public var previewBgColor = UIColor.black.withAlphaComponent(0.1)
-
- /// Preview selection mode, a background color for `Camera`, `Album`, `Cancel` buttons.
- @objc public var previewBtnBgColor = UIColor.white
-
- /// Preview selection mode, a text color for `Camera`, `Album`, `Cancel` buttons.
- @objc public var previewBtnTitleColor = UIColor.black
-
- /// Preview selection mode, cancel button title color when the selection amount is superior than 0.
- @objc public var previewBtnHighlightTitleColor = zlRGB(80, 169, 56)
-
- /// A color for navigation bar spinner.
- @objc public var navBarColor = zlRGB(160, 160, 160).withAlphaComponent(0.65)
-
- /// A color for Navigation bar text.
- @objc public var navTitleColor = UIColor.white
-
- /// The background color of the title view when the frame style is embedAlbumList.
- @objc public var navEmbedTitleViewBgColor = zlRGB(80, 80, 80)
-
- /// A color for background in album list.
- @objc public var albumListBgColor = zlRGB(45, 45, 45)
-
- /// A color for album list title label.
- @objc public var albumListTitleColor = UIColor.white
-
- /// A color for album list count label.
- @objc public var albumListCountColor = zlRGB(180, 180, 180)
-
- /// A color for album list separator.
- @objc public var separatorColor = zlRGB(60, 60, 60)
-
- /// A color for background in thumbnail interface.
- @objc public var thumbnailBgColor = zlRGB(50, 50, 50)
-
- /// A color for background in bottom tool view.
- @objc public var bottomToolViewBgColor = zlRGB(35, 35, 35).withAlphaComponent(0.3)
-
- /// The normal state title color of bottom tool view buttons.
- @objc public var bottomToolViewBtnNormalTitleColor = UIColor.white
-
- /// The disable state title color of bottom tool view buttons.
- @objc public var bottomToolViewBtnDisableTitleColor = zlRGB(168, 168, 168)
-
- /// The normal state background color of bottom tool view buttons.
- @objc public var bottomToolViewBtnNormalBgColor = zlRGB(80, 169, 56)
-
- /// The disable state background color of bottom tool view buttons.
- @objc public var bottomToolViewBtnDisableBgColor = zlRGB(50, 50, 50)
-
- /// With iOS14 limited authority, a color for select more photos at the bottom of the thumbnail interface.
- @objc public var selectMorePhotoWhenAuthIsLismitedTitleColor = UIColor.white
-
- /// The record progress color of custom camera.
- @objc public var cameraRecodeProgressColor = zlRGB(80, 169, 56)
-
- /// Mask layer color of selected cell.
- @objc public var selectedMaskColor = UIColor.black.withAlphaComponent(0.2)
-
- /// Border color of selected cell.
- @objc public var selectedBorderColor = zlRGB(80, 169, 56)
-
- /// Mask layer color of the cell that cannot be selected.
- @objc public var invalidMaskColor = UIColor.white.withAlphaComponent(0.5)
-
- /// The background color of selected cell index label.
- @objc public var indexLabelBgColor = zlRGB(80, 169, 56)
-
- /// The background color of camera cell inside album.
- @objc public var cameraCellBgColor = UIColor(white: 0.3, alpha: 1)
-
- }
- /// Font deply
- struct ZLCustomFontDeploy {
-
- static var fontName: String? = nil
-
- }
- /// Language deploy
- struct ZLCustomLanguageDeploy {
-
- static var language: ZLLanguageType = .system
-
- static var deploy: [ZLLocalLanguageKey: String] = [:]
-
- }
- /// Image source deploy
- struct ZLCustomImageDeploy {
-
- static var deploy: [String] = []
-
- }
- @objc public protocol ZLImageStickerContainerDelegate where Self: UIView {
-
- @objc var selectImageBlock: ( (UIImage) -> Void )? { get set }
-
- @objc var hideBlock: ( () -> Void )? { get set }
-
- @objc func show(in view: UIView)
-
- }
|