├── .github └── ISSUE_TEMPLATE │ ├── ----.md │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE.TXT ├── QMUIConfigurationTemplate ├── QMUIConfigurationTemplate.h └── QMUIConfigurationTemplate.m ├── QMUIKit.podspec ├── QMUIKit ├── Info.plist ├── PrivacyInfo.xcprivacy ├── QMUIComponents │ ├── AssetLibrary │ │ ├── QMUIAsset.h │ │ ├── QMUIAsset.m │ │ ├── QMUIAssetsGroup.h │ │ ├── QMUIAssetsGroup.m │ │ ├── QMUIAssetsManager.h │ │ └── QMUIAssetsManager.m │ ├── CAAnimation+QMUI.h │ ├── CAAnimation+QMUI.m │ ├── CALayer+QMUIViewAnimation.h │ ├── CALayer+QMUIViewAnimation.m │ ├── ImagePickerLibrary │ │ ├── QMUIAlbumViewController.h │ │ ├── QMUIAlbumViewController.m │ │ ├── QMUIImagePickerCollectionViewCell.h │ │ ├── QMUIImagePickerCollectionViewCell.m │ │ ├── QMUIImagePickerHelper.h │ │ ├── QMUIImagePickerHelper.m │ │ ├── QMUIImagePickerPreviewViewController.h │ │ ├── QMUIImagePickerPreviewViewController.m │ │ ├── QMUIImagePickerViewController.h │ │ └── QMUIImagePickerViewController.m │ ├── NavigationBarTransition │ │ ├── UINavigationBar+Transition.h │ │ ├── UINavigationBar+Transition.m │ │ ├── UINavigationController+NavigationBarTransition.h │ │ └── UINavigationController+NavigationBarTransition.m │ ├── QMUIAlertController.h │ ├── QMUIAlertController.m │ ├── QMUIAnimation │ │ ├── QMUIAnimationHelper.h │ │ ├── QMUIAnimationHelper.m │ │ ├── QMUIDisplayLinkAnimation.h │ │ ├── QMUIDisplayLinkAnimation.m │ │ └── QMUIEasings.h │ ├── QMUIAppearance.h │ ├── QMUIAppearance.m │ ├── QMUIBadge │ │ ├── QMUIBadgeLabel.h │ │ ├── QMUIBadgeLabel.m │ │ ├── QMUIBadgeProtocol.h │ │ ├── UIBarItem+QMUIBadge.h │ │ ├── UIBarItem+QMUIBadge.m │ │ ├── UIView+QMUIBadge.h │ │ └── UIView+QMUIBadge.m │ ├── QMUIButton │ │ ├── QMUIButton.h │ │ ├── QMUIButton.m │ │ ├── QMUINavigationButton.h │ │ ├── QMUINavigationButton.m │ │ ├── QMUIToolbarButton.h │ │ └── QMUIToolbarButton.m │ ├── QMUICellHeightCache.h │ ├── QMUICellHeightCache.m │ ├── QMUICellHeightKeyCache │ │ ├── QMUICellHeightKeyCache.h │ │ ├── QMUICellHeightKeyCache.m │ │ ├── UITableView+QMUICellHeightKeyCache.h │ │ └── UITableView+QMUICellHeightKeyCache.m │ ├── QMUICellSizeKeyCache │ │ ├── QMUICellSizeKeyCache.h │ │ ├── QMUICellSizeKeyCache.m │ │ ├── UICollectionView+QMUICellSizeKeyCache.h │ │ └── UICollectionView+QMUICellSizeKeyCache.m │ ├── QMUICheckbox.h │ ├── QMUICheckbox.m │ ├── QMUICollectionViewPagingLayout.h │ ├── QMUICollectionViewPagingLayout.m │ ├── QMUIConsole │ │ ├── QMUIConsole.h │ │ ├── QMUIConsole.m │ │ ├── QMUIConsoleToolbar.h │ │ ├── QMUIConsoleToolbar.m │ │ ├── QMUIConsoleViewController.h │ │ ├── QMUIConsoleViewController.m │ │ ├── QMUILog+QMUIConsole.h │ │ └── QMUILog+QMUIConsole.m │ ├── QMUIDialogViewController.h │ ├── QMUIDialogViewController.m │ ├── QMUIEmotionInputManager.h │ ├── QMUIEmotionInputManager.m │ ├── QMUIEmotionView.h │ ├── QMUIEmotionView.m │ ├── QMUIEmptyView.h │ ├── QMUIEmptyView.m │ ├── QMUIFloatLayoutView.h │ ├── QMUIFloatLayoutView.m │ ├── QMUIGridView.h │ ├── QMUIGridView.m │ ├── QMUIImagePreviewView │ │ ├── QMUIImagePreviewView.h │ │ ├── QMUIImagePreviewView.m │ │ ├── QMUIImagePreviewViewController.h │ │ ├── QMUIImagePreviewViewController.m │ │ ├── QMUIImagePreviewViewTransitionAnimator.h │ │ └── QMUIImagePreviewViewTransitionAnimator.m │ ├── QMUIKeyboardManager.h │ ├── QMUIKeyboardManager.m │ ├── QMUILabel.h │ ├── QMUILabel.m │ ├── QMUILayouter │ │ ├── QMUILayouter.h │ │ ├── QMUILayouterItem.h │ │ ├── QMUILayouterItem.m │ │ ├── QMUILayouterLinearHorizontal.h │ │ ├── QMUILayouterLinearHorizontal.m │ │ ├── QMUILayouterLinearVertical.h │ │ └── QMUILayouterLinearVertical.m │ ├── QMUILog │ │ ├── QMUILog.h │ │ ├── QMUILogItem.h │ │ ├── QMUILogItem.m │ │ ├── QMUILogNameManager.h │ │ ├── QMUILogNameManager.m │ │ ├── QMUILogger.h │ │ └── QMUILogger.m │ ├── QMUILogManagerViewController.h │ ├── QMUILogManagerViewController.m │ ├── QMUILogger+QMUIConfigurationTemplate.h │ ├── QMUILogger+QMUIConfigurationTemplate.m │ ├── QMUIMarqueeLabel.h │ ├── QMUIMarqueeLabel.m │ ├── QMUIModalPresentationViewController.h │ ├── QMUIModalPresentationViewController.m │ ├── QMUIMoreOperationController.h │ ├── QMUIMoreOperationController.m │ ├── QMUIMultipleDelegates │ │ ├── NSObject+QMUIMultipleDelegates.h │ │ ├── NSObject+QMUIMultipleDelegates.m │ │ ├── QMUIMultipleDelegates.h │ │ └── QMUIMultipleDelegates.m │ ├── QMUINavigationTitleView.h │ ├── QMUINavigationTitleView.m │ ├── QMUIOrderedDictionary.h │ ├── QMUIOrderedDictionary.m │ ├── QMUIPieProgressView.h │ ├── QMUIPieProgressView.m │ ├── QMUIPopupContainerView.h │ ├── QMUIPopupContainerView.m │ ├── QMUIPopupMenuView │ │ ├── QMUIPopupMenuItem.h │ │ ├── QMUIPopupMenuItem.m │ │ ├── QMUIPopupMenuItemView.h │ │ ├── QMUIPopupMenuItemView.m │ │ ├── QMUIPopupMenuItemViewProtocol.h │ │ ├── QMUIPopupMenuView.h │ │ └── QMUIPopupMenuView.m │ ├── QMUIScrollAnimator │ │ ├── QMUINavigationBarScrollingAnimator.h │ │ ├── QMUINavigationBarScrollingAnimator.m │ │ ├── QMUINavigationBarScrollingSnapAnimator.h │ │ ├── QMUINavigationBarScrollingSnapAnimator.m │ │ ├── QMUIScrollAnimator.h │ │ └── QMUIScrollAnimator.m │ ├── QMUISearchBar.h │ ├── QMUISearchBar.m │ ├── QMUISearchController.h │ ├── QMUISearchController.m │ ├── QMUISegmentedControl.h │ ├── QMUISegmentedControl.m │ ├── QMUISheetPresentation │ │ ├── QMUISheetPresentationNavigationBar.h │ │ ├── QMUISheetPresentationNavigationBar.m │ │ ├── QMUISheetPresentationSupports.h │ │ └── QMUISheetPresentationSupports.m │ ├── QMUITableView.h │ ├── QMUITableView.m │ ├── QMUITableViewCell.h │ ├── QMUITableViewCell.m │ ├── QMUITableViewHeaderFooterView.h │ ├── QMUITableViewHeaderFooterView.m │ ├── QMUITableViewProtocols.h │ ├── QMUITestView.h │ ├── QMUITestView.m │ ├── QMUITextField.h │ ├── QMUITextField.m │ ├── QMUITextView.h │ ├── QMUITextView.m │ ├── QMUITheme │ │ ├── QMUITheme.h │ │ ├── QMUIThemeManager.h │ │ ├── QMUIThemeManager.m │ │ ├── QMUIThemeManagerCenter.h │ │ ├── QMUIThemeManagerCenter.m │ │ ├── QMUIThemePrivate.h │ │ ├── QMUIThemePrivate.m │ │ ├── UIColor+QMUITheme.h │ │ ├── UIColor+QMUITheme.m │ │ ├── UIImage+QMUITheme.h │ │ ├── UIImage+QMUITheme.m │ │ ├── UIView+QMUITheme.h │ │ ├── UIView+QMUITheme.m │ │ ├── UIViewController+QMUITheme.h │ │ ├── UIViewController+QMUITheme.m │ │ ├── UIVisualEffect+QMUITheme.h │ │ └── UIVisualEffect+QMUITheme.m │ ├── QMUITips.h │ ├── QMUITips.m │ ├── QMUIWeakObjectContainer.h │ ├── QMUIWeakObjectContainer.m │ ├── QMUIWindowSizeMonitor.h │ ├── QMUIWindowSizeMonitor.m │ ├── QMUIZoomImageView.h │ ├── QMUIZoomImageView.m │ ├── StaticTableView │ │ ├── QMUIStaticTableViewCellData.h │ │ ├── QMUIStaticTableViewCellData.m │ │ ├── QMUIStaticTableViewCellDataSource.h │ │ ├── QMUIStaticTableViewCellDataSource.m │ │ ├── UITableView+QMUIStaticCell.h │ │ └── UITableView+QMUIStaticCell.m │ └── ToastView │ │ ├── QMUIToastAnimator.h │ │ ├── QMUIToastAnimator.m │ │ ├── QMUIToastBackgroundView.h │ │ ├── QMUIToastBackgroundView.m │ │ ├── QMUIToastContentView.h │ │ ├── QMUIToastContentView.m │ │ ├── QMUIToastView.h │ │ └── QMUIToastView.m ├── QMUICore │ ├── QMUICommonDefines.h │ ├── QMUIConfiguration.h │ ├── QMUIConfiguration.m │ ├── QMUIConfigurationMacros.h │ ├── QMUICore.h │ ├── QMUIHelper.h │ ├── QMUIHelper.m │ ├── QMUILab.h │ ├── QMUIRuntime.h │ └── QMUIRuntime.m ├── QMUIKit.h ├── QMUIMainFrame │ ├── QMUICommonTableViewController.h │ ├── QMUICommonTableViewController.m │ ├── QMUICommonViewController.h │ ├── QMUICommonViewController.m │ ├── QMUINavigationController.h │ ├── QMUINavigationController.m │ ├── QMUITabBarViewController.h │ └── QMUITabBarViewController.m ├── QMUIResources │ └── Images.xcassets │ │ ├── Contents.json │ │ ├── QMUI_checkbox16.imageset │ │ ├── Contents.json │ │ └── QMUI_checkbox16.pdf │ │ ├── QMUI_checkbox16_checked.imageset │ │ ├── Contents.json │ │ └── QMUI_checkbox16_checked.pdf │ │ ├── QMUI_checkbox16_disabled.imageset │ │ ├── Contents.json │ │ └── QMUI_checkbox16_disabled.pdf │ │ ├── QMUI_checkbox16_indeterminate.imageset │ │ ├── Contents.json │ │ └── QMUI_checkbox16_indeterminate.pdf │ │ ├── QMUI_console_clear.imageset │ │ ├── Contents.json │ │ └── QMUI_console_clear.pdf │ │ ├── QMUI_console_filter.imageset │ │ ├── Contents.json │ │ └── QMUI_console_filter.pdf │ │ ├── QMUI_console_filter_selected.imageset │ │ ├── Contents.json │ │ └── QMUI_console_filter_selected.pdf │ │ ├── QMUI_console_logo.imageset │ │ ├── Contents.json │ │ └── QMUI_console_logo.pdf │ │ ├── QMUI_emotion_delete.imageset │ │ ├── Contents.json │ │ └── QMUI_emotion_delete.pdf │ │ ├── QMUI_hiddenAlbum.imageset │ │ ├── Contents.json │ │ └── QMUI_hiddenAlbum.pdf │ │ ├── QMUI_icloud_download_fault.imageset │ │ ├── Contents.json │ │ └── QMUI_icloud_download_fault.pdf │ │ ├── QMUI_pickerImage_checkbox.imageset │ │ ├── Contents.json │ │ └── QMUI_pickerImage_checkbox.pdf │ │ ├── QMUI_pickerImage_checkbox_checked.imageset │ │ ├── Contents.json │ │ └── QMUI_pickerImage_checkbox_checked.pdf │ │ ├── QMUI_pickerImage_favorite.imageset │ │ ├── Contents.json │ │ └── QMUI_pickerImage_favorite.pdf │ │ ├── QMUI_pickerImage_video_mark.imageset │ │ ├── Contents.json │ │ └── QMUI_pickerImage_video_mark.pdf │ │ ├── QMUI_previewImage_checkbox.imageset │ │ ├── Contents.json │ │ └── QMUI_previewImage_checkbox.pdf │ │ ├── QMUI_previewImage_checkbox_checked.imageset │ │ ├── Contents.json │ │ └── QMUI_previewImage_checkbox_checked.pdf │ │ ├── QMUI_tips_done.imageset │ │ ├── Contents.json │ │ └── QMUI_tips_done.pdf │ │ ├── QMUI_tips_error.imageset │ │ ├── Contents.json │ │ └── QMUI_tips_error.pdf │ │ └── QMUI_tips_info.imageset │ │ ├── Contents.json │ │ └── QMUI_tips_info.pdf └── UIKitExtensions │ ├── CALayer+QMUI.h │ ├── CALayer+QMUI.m │ ├── NSArray+QMUI.h │ ├── NSArray+QMUI.m │ ├── NSAttributedString+QMUI.h │ ├── NSAttributedString+QMUI.m │ ├── NSCharacterSet+QMUI.h │ ├── NSCharacterSet+QMUI.m │ ├── NSDictionary+QMUI.h │ ├── NSDictionary+QMUI.m │ ├── NSMethodSignature+QMUI.h │ ├── NSMethodSignature+QMUI.m │ ├── NSNumber+QMUI.h │ ├── NSNumber+QMUI.m │ ├── NSObject+QMUI.h │ ├── NSObject+QMUI.m │ ├── NSParagraphStyle+QMUI.h │ ├── NSParagraphStyle+QMUI.m │ ├── NSPointerArray+QMUI.h │ ├── NSPointerArray+QMUI.m │ ├── NSRegularExpression+QMUI.h │ ├── NSRegularExpression+QMUI.m │ ├── NSShadow+QMUI.h │ ├── NSShadow+QMUI.m │ ├── NSString+QMUI.h │ ├── NSString+QMUI.m │ ├── NSURL+QMUI.h │ ├── NSURL+QMUI.m │ ├── QMUIBarProtocol │ ├── QMUIBarProtocol.h │ ├── QMUIBarProtocolPrivate.h │ ├── QMUIBarProtocolPrivate.m │ ├── UINavigationBar+QMUIBarProtocol.h │ ├── UINavigationBar+QMUIBarProtocol.m │ ├── UITabBar+QMUIBarProtocol.h │ └── UITabBar+QMUIBarProtocol.m │ ├── QMUIStringPrivate.h │ ├── QMUIStringPrivate.m │ ├── UIActivityIndicatorView+QMUI.h │ ├── UIActivityIndicatorView+QMUI.m │ ├── UIApplication+QMUI.h │ ├── UIApplication+QMUI.m │ ├── UIBarItem+QMUI.h │ ├── UIBarItem+QMUI.m │ ├── UIBezierPath+QMUI.h │ ├── UIBezierPath+QMUI.m │ ├── UIBlurEffect+QMUI.h │ ├── UIBlurEffect+QMUI.m │ ├── UIButton+QMUI.h │ ├── UIButton+QMUI.m │ ├── UICollectionView+QMUI.h │ ├── UICollectionView+QMUI.m │ ├── UICollectionViewCell+QMUI.h │ ├── UICollectionViewCell+QMUI.m │ ├── UIColor+QMUI.h │ ├── UIColor+QMUI.m │ ├── UIControl+QMUI.h │ ├── UIControl+QMUI.m │ ├── UIFont+QMUI.h │ ├── UIFont+QMUI.m │ ├── UIGestureRecognizer+QMUI.h │ ├── UIGestureRecognizer+QMUI.m │ ├── UIImage+QMUI.h │ ├── UIImage+QMUI.m │ ├── UIImageView+QMUI.h │ ├── UIImageView+QMUI.m │ ├── UIInterface+QMUI.h │ ├── UIInterface+QMUI.m │ ├── UILabel+QMUI.h │ ├── UILabel+QMUI.m │ ├── UIMenuController+QMUI.h │ ├── UIMenuController+QMUI.m │ ├── UINavigationBar+QMUI.h │ ├── UINavigationBar+QMUI.m │ ├── UINavigationController+QMUI.h │ ├── UINavigationController+QMUI.m │ ├── UINavigationItem+QMUI.h │ ├── UINavigationItem+QMUI.m │ ├── UIScrollView+QMUI.h │ ├── UIScrollView+QMUI.m │ ├── UISearchBar+QMUI.h │ ├── UISearchBar+QMUI.m │ ├── UISearchController+QMUI.h │ ├── UISearchController+QMUI.m │ ├── UISlider+QMUI.h │ ├── UISlider+QMUI.m │ ├── UISwitch+QMUI.h │ ├── UISwitch+QMUI.m │ ├── UITabBar+QMUI.h │ ├── UITabBar+QMUI.m │ ├── UITabBarItem+QMUI.h │ ├── UITabBarItem+QMUI.m │ ├── UITableView+QMUI.h │ ├── UITableView+QMUI.m │ ├── UITableViewCell+QMUI.h │ ├── UITableViewCell+QMUI.m │ ├── UITableViewHeaderFooterView+QMUI.h │ ├── UITableViewHeaderFooterView+QMUI.m │ ├── UITextField+QMUI.h │ ├── UITextField+QMUI.m │ ├── UITextInputTraits+QMUI.h │ ├── UITextInputTraits+QMUI.m │ ├── UITextView+QMUI.h │ ├── UITextView+QMUI.m │ ├── UIToolbar+QMUI.h │ ├── UIToolbar+QMUI.m │ ├── UITraitCollection+QMUI.h │ ├── UITraitCollection+QMUI.m │ ├── UIView+QMUI.h │ ├── UIView+QMUI.m │ ├── UIView+QMUIBorder.h │ ├── UIView+QMUIBorder.m │ ├── UIViewController+QMUI.h │ ├── UIViewController+QMUI.m │ ├── UIVisualEffectView+QMUI.h │ ├── UIVisualEffectView+QMUI.m │ ├── UIWindow+QMUI.h │ └── UIWindow+QMUI.m ├── QMUIKitTests ├── Components │ └── QMUIThemeTests.m ├── Core │ └── QMUICommonDefinesTests.m ├── Info.plist └── UIKitExtensions │ ├── NSObjectTests.m │ ├── NSStringTests.m │ ├── UIButtonTests.m │ └── UIColorTests.m ├── README.md ├── add_license.py ├── new_license_content.txt ├── old_license_content.txt ├── qmui.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── molice.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcshareddata │ └── xcschemes │ ├── QMUIKit.xcscheme │ └── QMUIKitTests.xcscheme └── umbrellaHeaderFileCreator.py /.github/ISSUE_TEMPLATE/----.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 使用方式 3 | about: 咨询 QMUI 某些功能的用法 4 | title: '' 5 | labels: help wanted 6 | assignees: '' 7 | 8 | --- 9 | 10 | QMUI 已经提供了**详尽的注释文档**,以及**完整的示例项目 [QMUI Demo](https://github.com/QMUI/QMUI_iOS_Demo)**,当你遇到某些功能不知道怎么使用,或者想知道 QMUI 是否有提供某些功能时,请先查看注释文档或者 Demo,找不到了再提 issue。若提的 issue 已有明确注释或示例的,**可能会被直接关闭或得不到及时的回复**,请知悉。 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug 3 | about: QMUIKit 框架本身的 bug(请注意区分非 QMUIKit 代码引发的问题) 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Bug 表现** 11 | 问题的具体描述 12 | 13 | **截图** 14 | Bug 现场的界面截图,或者 Xcode 控制台的错误信息截图,有问题的代码截图 15 | 16 | **如何重现** 17 | 1. ... 18 | 2. ... 19 | 20 | **预期的表现** 21 | 正常情况下,应该是什么表现 22 | 23 | **其他信息** 24 | - 设备: [例如模拟器、iPhone、iPad] 25 | - iOS 版本: [iOS 14.x] 26 | - Xcode 版本: [Xcode 12.x] 27 | - QMUI 版本: [4.x.x] 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 意见与建议 3 | about: 功能、接口设计等的相关建议 4 | title: '' 5 | labels: suggest 6 | assignees: '' 7 | 8 | --- 9 | 10 | **现存问题或期望目标** 11 | 对于功能的建议,请说明具体的场景,现在的代码为什么无法实现需求。 12 | 对于代码设计方面的建议,请说明目前的问题所在。 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | xcuserdata/ 3 | 4 | 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | [腾讯开源激励计划](https://opensource.tencent.com/contribution) 鼓励开发者的参与和贡献,期待你的加入。我们欢迎 [report Issues](https://github.com/QMUI/QMUI_iOS/issues) 或者 [pull requests](https://github.com/QMUI/QMUI_iOS/pulls)。 在贡献代码之前请阅读以下指引。 2 | 3 | ## 问题管理 4 | 我们用 Github Issues 去跟踪 public bugs 和 feature requests。 5 | 6 | ### 使用 Issues 7 | 8 | 1. 新建 issues 前,请查找已存在或者相类似的 issue,从而保证不存在冗余。 9 | 2. 新建 issues 时,请根据我们提供的 issue 模板,尽可能提供详细的描述、截屏或者短视频来辅助我们定位问题。 10 | 11 | ### Pull Requests 12 | 13 | 我们欢迎大家为 QMUI_iOS 贡献代码,在完成一个 pull request 之前请确认: 14 | 15 | 1. 从 `master` fork 你自己的分支。 16 | 2. 在修改了代码之后请修改对应的文档和注释。 17 | 3. 在新建的文件中请加入 licence 和 copy right 声明。 18 | 4. 确保一致的代码风格。 19 | 5. 做充分的测试。 20 | -------------------------------------------------------------------------------- /LICENSE.TXT: -------------------------------------------------------------------------------- 1 | Tencent is pleased to support the open source community by making QMUI_iOS available. 2 | Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 3 | If you have downloaded a copy of the QMUI_iOS binary from Tencent, please note that the QMUI_iOS binary is licensed under the MIT License. 4 | If you have downloaded a copy of the QMUI_iOS source code from Tencent, please note that QMUI_iOS source code is licensed under the MIT License. Your integration of QMUI_iOS into your own projects may require compliance with the MIT License. 5 | A copy of the MIT License is included in this file. 6 | 7 | 8 | Terms of the MIT License: 9 | --------------------------------------------------- 10 | 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: 11 | 12 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 13 | 14 | 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. 15 | -------------------------------------------------------------------------------- /QMUIConfigurationTemplate/QMUIConfigurationTemplate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUIConfigurationTemplate.h 11 | // 12 | // Created by QMUI Team on 15/3/29. 13 | // 14 | 15 | #import 16 | #import 17 | 18 | /** 19 | * QMUIConfigurationTemplate 是一份配置表,用于配合 QMUIConfiguration 来管理整个 App 的全局样式,使用方式: 20 | * 在 QMUI 项目代码的文件夹里找到 QMUIConfigurationTemplate 目录,把里面所有文件复制到自己项目里,保证能被编译到即可,不需要在某些地方 import,也不需要手动运行。 21 | * 22 | * @warning 更新 QMUIKit 的版本时,请留意 Release Log 里是否有提醒更新配置表,请尽量保持自己项目里的配置表与 QMUIKit 里的配置表一致,避免遗漏新的属性。 23 | * @warning 配置表的 class 名必须以 QMUIConfigurationTemplate 开头,并且实现 ,因为这两者是 QMUI 识别该 NSObject 是否为一份配置表的条件。 24 | * @warning QMUI 2.3.0 之后,配置表改为自动运行,不需要再在某个地方手动运行了。 25 | */ 26 | @interface QMUIConfigurationTemplate : NSObject 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /QMUIKit/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | $(MARKETING_VERSION) 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /QMUIKit/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyAccessedAPITypes 6 | 7 | 8 | NSPrivacyAccessedAPIType 9 | NSPrivacyAccessedAPICategoryUserDefaults 10 | NSPrivacyAccessedAPITypeReasons 11 | 12 | CA92.1 13 | 14 | 15 | 16 | NSPrivacyCollectedDataTypes 17 | 18 | NSPrivacyTrackingDomains 19 | 20 | NSPrivacyTracking 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/CAAnimation+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // CAAnimation+QMUI.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/7/31. 14 | // 15 | 16 | #import 17 | 18 | // 这个文件依赖了 QMUIMultipleDelegates,无法作为 UIKitExtensions 的一部分,所以放在 QMUIComponents 内 19 | 20 | @interface CAAnimation (QMUI) 21 | 22 | @property(nonatomic, copy) void (^qmui_animationDidStartBlock)(__kindof CAAnimation *aAnimation); 23 | @property(nonatomic, copy) void (^qmui_animationDidStopBlock)(__kindof CAAnimation *aAnimation, BOOL finished); 24 | @end 25 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/CALayer+QMUIViewAnimation.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // CALayer+QMUIViewAnimation.h 10 | // QMUIKit 11 | // 12 | // Created by ziezheng on 2020/4/4. 13 | // 14 | 15 | #import 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | @interface CALayer (QMUIViewAnimation) 20 | 21 | /** 22 | 开启了该属性的 CALayer 可在 +[UIView animateWithDuration:animations:] 执行动画,系统默认是不支持这种做法的。 23 | 24 | @code 25 | [UIView animateWithDuration:1 animations:^{ 26 | layer.frame = xxx; 27 | } completion:nil]; 28 | @endcode 29 | */ 30 | @property(nonatomic, assign) BOOL qmui_viewAnimationEnabled; 31 | 32 | @end 33 | 34 | NS_ASSUME_NONNULL_END 35 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/NavigationBarTransition/UINavigationBar+Transition.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UINavigationBar+Transition.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 11/25/16. 14 | // 15 | 16 | #import 17 | 18 | @interface UINavigationBar (Transition) 19 | 20 | /// 用来模仿真的navBar,配合 UINavigationController+NavigationBarTransition 在转场过程中存在的一条假navBar 21 | @property(nonatomic, weak) UINavigationBar *qmuinb_copyStylesToBar; 22 | @end 23 | 24 | @interface _QMUITransitionNavigationBar : UINavigationBar 25 | 26 | @property(nonatomic, weak) UIViewController *parentViewController; 27 | 28 | // 建立假 bar 到真 bar 的关系,内部会通过 qmuinb_copyStylesToBar 同时设置真 bar 到假 bar 的关系 29 | @property(nonatomic, weak) UINavigationBar *originalNavigationBar; 30 | 31 | @property(nonatomic, assign) BOOL shouldPreventAppearance; 32 | 33 | // 根据当前的系统导航栏布局,刷新自身在 vc.view 上的布局 34 | - (void)updateLayout; 35 | @end 36 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/NavigationBarTransition/UINavigationController+NavigationBarTransition.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UINavigationController+NavigationBarTransition.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 16/2/22. 14 | // 15 | 16 | #import 17 | #import 18 | 19 | /** 20 | * 因为系统的UINavigationController只有一个navBar,所以会导致在切换controller的时候,如果两个controller的navBar状态不一致(包括backgroundImgae、shadowImage、barTintColor等等),就会导致在刚要切换的瞬间,navBar的状态都立马变成下一个controller所设置的样式了,为了解决这种情况,QMUI给出了一个方案,有四个方法可以决定你在转场的时候要不要使用自定义的navBar来模仿真实的navBar。 21 | */ 22 | @interface UINavigationController (NavigationBarTransition) 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIAppearance.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // QMUIAppearance.h 10 | // QMUIKit 11 | // 12 | // Created by MoLice on 2020/3/25. 13 | // 14 | 15 | #import 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | /** 20 | UIKit 仅提供了对 UIView 默认的 UIAppearance 支持,如果你是一个继承自 NSObject 的对象,想要使用 UIAppearance 能力,按 UIKit 公开的 API 是无法实现的,而 QMUIAppearance 对这种场景提供了支持。 21 | 22 | 使用方法(可参考 QMUIAlertController): 23 | 24 | 1. 为目标类增加方法 +(instancetype)appearance; 方法,返回值类型使用 instancetype 是为了保证 Xcode 能正确进行代码提示,命名无限制,用 appearance 只是为了统一。 25 | 26 | 2. 为目标类支持 appearance 的属性、方法添加 UI_APPEARANCE_SELECTOR 标记,注意对于方法只有符合特定命名格式才支持,具体请查看 UIAppearance.h 顶部对宏 UI_APPEARANCE_SELECTOR 的注释。 27 | 28 | 3. 在 +appearance 方法里通过 +[QMUIAppearance appearanceForClass:self] 得到 appearance 对象并返回。 29 | 30 | 4. 在恰当的时机为目标类的 appearance 赋初始值,QMUI 通常在类的 +initialize 方法里赋值。如果你支持 UI_APPEARANCE_SELECTOR 的属性默认值都为 nil,也可以忽略这一步。 31 | 32 | 5. 在类初始化实例的时候(例如 init 方法里)调用 -qmui_applyQMUIAppearance 为实例赋初始值,注意如果你的父类已经调用过的话,子类不需要再重复调用。 33 | 34 | @note 特别的,如果你正在为一个 UIView 子类支持 UIAppearance,不需要用到 QMUIAppearance,直接将属性、方法加上 UI_APPEARANCE_SELECTOR 标记即可,也不需要通过 -qmui_applyAppearance 的方式赋初始值(除非你希望这个赋值时机提前,系统默认时机是在 didMoveToWindow 时),系统都已经帮你处理好了,具体可查看 UIKit Documentation。 35 | */ 36 | @interface QMUIAppearance : NSObject 37 | 38 | /** 39 | 获取指定 Class 的 appearance 对象,每个 Class 全局只会存在一个 appearance 对象。 40 | */ 41 | + (id)appearanceForClass:(Class)aClass; 42 | @end 43 | 44 | @interface NSObject (QMUIAppearnace) 45 | 46 | /** 47 | 从 appearance 里取值并赋值给当前实例,通常在对象的 init 里调用(只要在实例初始化后、使用前就可以)。适用于 QMUIAppearance 和系统的 UIAppearance。 48 | */ 49 | - (void)qmui_applyAppearance; 50 | @end 51 | 52 | NS_ASSUME_NONNULL_END 53 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIBadge/QMUIBadgeLabel.h: -------------------------------------------------------------------------------- 1 | // 2 | // QMUIBadgeLabel.h 3 | // QMUIKit 4 | // 5 | // Created by molice on 2023/7/26. 6 | // Copyright © 2023 QMUI Team. All rights reserved. 7 | // 8 | 9 | #import "QMUILabel.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface QMUIBadgeLabel : QMUILabel 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIBadge/QMUIBadgeLabel.m: -------------------------------------------------------------------------------- 1 | // 2 | // QMUIBadgeLabel.m 3 | // QMUIKit 4 | // 5 | // Created by molice on 2023/7/26. 6 | // Copyright © 2023 QMUI Team. All rights reserved. 7 | // 8 | 9 | #import "QMUIBadgeLabel.h" 10 | #import "QMUICore.h" 11 | 12 | @implementation QMUIBadgeLabel 13 | 14 | - (instancetype)initWithFrame:(CGRect)frame { 15 | if (self = [super initWithFrame:frame]) { 16 | self.clipsToBounds = YES; 17 | self.textAlignment = NSTextAlignmentCenter; 18 | if (@available(iOS 13.0, *)) { 19 | self.layer.cornerCurve = kCACornerCurveContinuous; 20 | } 21 | 22 | if (QMUICMIActivated) { 23 | self.backgroundColor = BadgeBackgroundColor; 24 | self.textColor = BadgeTextColor; 25 | self.font = BadgeFont; 26 | self.contentEdgeInsets = BadgeContentEdgeInsets; 27 | } else { 28 | self.backgroundColor = UIColorRed; 29 | self.textColor = UIColorWhite; 30 | self.font = UIFontBoldMake(11); 31 | self.contentEdgeInsets = UIEdgeInsetsMake(2, 4, 2, 4); 32 | } 33 | } 34 | return self; 35 | } 36 | 37 | - (CGSize)sizeThatFits:(CGSize)size { 38 | if (self.attributedText.length == 1) { 39 | NSMutableAttributedString *text = self.attributedText.mutableCopy; 40 | [text replaceCharactersInRange:NSMakeRange(0, 1) withString:@"8"]; 41 | CGSize textSize = [text boundingRectWithSize:CGSizeMax options:NSStringDrawingUsesLineFragmentOrigin context:nil].size; 42 | CGSize result = CGSizeFlatted(CGSizeMake(textSize.width + UIEdgeInsetsGetHorizontalValue(self.contentEdgeInsets), textSize.height + UIEdgeInsetsGetVerticalValue(self.contentEdgeInsets))); 43 | result.width = MAX(result.width, result.height); 44 | result.height = result.width; 45 | return result; 46 | } 47 | CGSize result = [super sizeThatFits:size]; 48 | return result; 49 | } 50 | 51 | - (void)layoutSubviews { 52 | [super layoutSubviews]; 53 | self.layer.cornerRadius = MIN(CGRectGetWidth(self.bounds) / 2, CGRectGetHeight(self.bounds) / 2); 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIBadge/UIBarItem+QMUIBadge.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UIBarItem+QMUIBadge.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/6/2. 14 | // 15 | 16 | #import 17 | #import 18 | #import "QMUIBadgeProtocol.h" 19 | 20 | /** 21 | * 用于在 UIBarButtonItem(通常用于 UINavigationBar 和 UIToolbar)和 UITabBarItem 上显示未读红点或者未读数,对设置的时机没有要求。 22 | * 提供的属性请查看 @c QMUIBadgeProtocol ,属性的默认值在 QMUIConfigurationTemplate 配置表里设置,如果不使用配置表,则所有属性的默认值均为 0 或 nil。 23 | * 24 | * @note 系统对 UIBarButtonItem 和 UITabBarItem 在横竖屏下均会有不同的布局,当你使用本控件时建议分别检查横竖屏下的表现是否正确。 25 | */ 26 | @interface UIBarItem (QMUIBadge) 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIBadge/UIView+QMUIBadge.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UIView+QMUIBadge.h 11 | // QMUIKit 12 | // 13 | // Created by MoLice on 2020/5/26. 14 | // 15 | 16 | #import 17 | #import "QMUIBadgeProtocol.h" 18 | 19 | NS_ASSUME_NONNULL_BEGIN 20 | 21 | /** 22 | 用于在任意 UIView 上显示未读红点或者未读数,提供的属性请查看 @c QMUIBadgeProtocol ,属性的默认值在 QMUIConfigurationTemplate 配置表里设置,如果不使用配置表,则所有属性的默认值均为 0 或 nil。 23 | 24 | @note 使用该组件会强制设置 view.clipsToBounds = NO 以避免布局到 view 外部的红点/未读数看不到。 25 | */ 26 | @interface UIView (QMUIBadge) 27 | 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIButton/QMUIToolbarButton.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUIToolbarButton.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/4/9. 14 | // 15 | 16 | #import 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | typedef NS_ENUM(NSUInteger, QMUIToolbarButtonType) { 21 | QMUIToolbarButtonTypeNormal, // 普通工具栏按钮 22 | QMUIToolbarButtonTypeRed, // 工具栏红色按钮,用于删除等警告性操作 23 | QMUIToolbarButtonTypeImage, // 图标类型的按钮 24 | }; 25 | 26 | /** 27 | * `QMUIToolbarButton`是用于底部工具栏的按钮 28 | */ 29 | @interface QMUIToolbarButton : UIButton 30 | 31 | /// 获取当前按钮的type 32 | @property(nonatomic, assign, readonly) QMUIToolbarButtonType type; 33 | 34 | /** 35 | * 工具栏按钮的初始化函数 36 | * @param type 按钮类型 37 | */ 38 | - (instancetype)initWithType:(QMUIToolbarButtonType)type; 39 | 40 | /** 41 | * 工具栏按钮的初始化函数 42 | * @param type 按钮类型 43 | * @param title 按钮的title 44 | */ 45 | - (instancetype)initWithType:(QMUIToolbarButtonType)type title:(nullable NSString *)title; 46 | 47 | /** 48 | * 工具栏按钮的初始化函数 49 | * @param image 按钮的image 50 | */ 51 | - (instancetype)initWithImage:(UIImage *)image; 52 | 53 | /// 在原有的QMUIToolbarButton上创建一个UIBarButtonItem 54 | + (nullable UIBarButtonItem *)barButtonItemWithToolbarButton:(QMUIToolbarButton *)button target:(nullable id)target action:(nullable SEL)selector; 55 | 56 | /// 创建一个特定type的UIBarButtonItem 57 | + (nullable UIBarButtonItem *)barButtonItemWithType:(QMUIToolbarButtonType)type title:(nullable NSString *)title target:(nullable id)target action:(nullable SEL)selector; 58 | 59 | /// 创建一个图标类型的UIBarButtonItem 60 | + (nullable UIBarButtonItem *)barButtonItemWithImage:(nullable UIImage *)image target:(nullable id)target action:(nullable SEL)selector; 61 | 62 | @end 63 | 64 | NS_ASSUME_NONNULL_END 65 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUICellHeightKeyCache/QMUICellHeightKeyCache.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUICellHeightKeyCache.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/3/14. 14 | // 15 | 16 | #import 17 | #import 18 | 19 | NS_ASSUME_NONNULL_BEGIN 20 | 21 | /** 22 | * 通过业务定义的一个 key 来缓存 cell 的高度,需搭配 UITableView 使用,一般不用你自己去 init。 23 | * 具体使用方式请看 UITableView (QMUICellHeightKeyCache) 的注释。 24 | */ 25 | @interface QMUICellHeightKeyCache : NSObject 26 | 27 | /// 检查是否存在某个 key 的高度 28 | - (BOOL)existsHeightForKey:(id)key; 29 | 30 | /// 将某个高度缓存到指定的 key 31 | - (void)cacheHeight:(CGFloat)height forKey:(id)key; 32 | 33 | /// 获取指定 key 对应的高度,如果该 key 不存在,则返回 0 34 | - (CGFloat)heightForKey:(id)key; 35 | 36 | /// 令指定 key 的缓存失效。注意如果在业务里,应该调用 [UITableView -qmui_invalidateCellHeightCachedForKey:],而不应该直接调用这个方法。 37 | - (void)invalidateHeightForKey:(id)key; 38 | 39 | /// 令所有的缓存失效。注意如果在业务里,应该调用 [UITableView -qmui_invalidateAllCellHeightKeyCache],而不应该直接调用这个方法。 40 | - (void)invalidateAllHeightCache; 41 | 42 | @end 43 | 44 | NS_ASSUME_NONNULL_END 45 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUICellHeightKeyCache/QMUICellHeightKeyCache.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUICellHeightKeyCache.m 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/3/14. 14 | // 15 | 16 | #import "QMUICellHeightKeyCache.h" 17 | #import "NSNumber+QMUI.h" 18 | 19 | @interface QMUICellHeightKeyCache () 20 | 21 | @property(nonatomic, strong) NSMutableDictionary, NSNumber *> *cachedHeights; 22 | @end 23 | 24 | @implementation QMUICellHeightKeyCache 25 | 26 | - (instancetype)init { 27 | if (self = [super init]) { 28 | self.cachedHeights = [NSMutableDictionary dictionary]; 29 | } 30 | return self; 31 | } 32 | 33 | - (BOOL)existsHeightForKey:(id)key { 34 | NSNumber *number = self.cachedHeights[key]; 35 | return !!number;// 注意这里“拿 number 是否存在”作为条件,也即意味着高度为0也是合法的,因为 @(0) 也是一个不为 nil 的 NSNumber 36 | } 37 | 38 | - (void)cacheHeight:(CGFloat)height forKey:(id)key { 39 | self.cachedHeights[key] = @(height); 40 | } 41 | 42 | - (CGFloat)heightForKey:(id)key { 43 | return self.cachedHeights[key].qmui_CGFloatValue; 44 | } 45 | 46 | - (void)invalidateHeightForKey:(id)key { 47 | [self.cachedHeights removeObjectForKey:key]; 48 | } 49 | 50 | - (void)invalidateAllHeightCache { 51 | [self.cachedHeights removeAllObjects]; 52 | } 53 | 54 | - (NSString *)description { 55 | return [NSString stringWithFormat:@"%@, cachedHeights = %@", [super description], _cachedHeights]; 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUICellSizeKeyCache/QMUICellSizeKeyCache.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUICellSizeKeyCache.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/3/14. 14 | // 15 | 16 | #import 17 | #import 18 | 19 | /** 20 | * 通过业务定义的一个 key 来缓存 cell 的 size,需搭配 UICollectionView 使用,一般不用你自己去 init。 21 | * 具体使用方式请看 UICollectionView (QMUICellSizeKeyCache) 的注释。 22 | */ 23 | @interface QMUICellSizeKeyCache : NSObject 24 | 25 | /// 检查是否存在某个 key 的 size 26 | - (BOOL)existsSizeForKey:(id)key; 27 | 28 | /// 将某个 size 缓存到指定的 key 29 | - (void)cacheSize:(CGSize)size forKey:(id)key; 30 | 31 | /// 获取指定 key 对应的 size,如果该 key 不存在,则返回 0 32 | - (CGSize)sizeForKey:(id)key; 33 | 34 | // 使 cache 失效,多用在 data 更新之后或 UICollectionView 的 size 发生变化的时候,但在 QMUI 里,UICollectionView 的 size 发生变化会自动更新,所以不用处理 size 变化的场景。 35 | - (void)invalidateSizeForKey:(id)key; 36 | - (void)invalidateAllSizeCache; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUICellSizeKeyCache/QMUICellSizeKeyCache.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUICellSizeKeyCache.m 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/3/14. 14 | // 15 | 16 | #import "QMUICellSizeKeyCache.h" 17 | 18 | @interface QMUICellSizeKeyCache () 19 | 20 | @property(nonatomic, strong) NSMutableDictionary, NSValue *> *cachedSizes; 21 | @end 22 | 23 | @implementation QMUICellSizeKeyCache 24 | 25 | - (instancetype)init { 26 | if (self = [super init]) { 27 | self.cachedSizes = [NSMutableDictionary dictionary]; 28 | } 29 | return self; 30 | } 31 | 32 | - (BOOL)existsSizeForKey:(id)key { 33 | NSValue *sizeValue = self.cachedSizes[key]; 34 | return sizeValue && !CGSizeEqualToSize(sizeValue.CGSizeValue, CGSizeMake(-1, -1)); 35 | } 36 | 37 | - (void)cacheSize:(CGSize)size forKey:(id)key { 38 | self.cachedSizes[key] = @(size); 39 | } 40 | 41 | - (CGSize)sizeForKey:(id)key { 42 | return self.cachedSizes[key].CGSizeValue; 43 | } 44 | 45 | - (void)invalidateSizeForKey:(id)key { 46 | [self.cachedSizes removeObjectForKey:key]; 47 | } 48 | 49 | - (void)invalidateAllSizeCache { 50 | [self.cachedSizes removeAllObjects]; 51 | } 52 | 53 | - (NSString *)description { 54 | return [NSString stringWithFormat:@"%@, cachedSizes = %@", [super description], _cachedSizes]; 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUICellSizeKeyCache/UICollectionView+QMUICellSizeKeyCache.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UICollectionView+QMUICellSizeKeyCache.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/3/14. 14 | // 15 | 16 | #import 17 | #import 18 | 19 | @class QMUICellSizeKeyCache; 20 | 21 | @protocol QMUICellSizeKeyCache_UICollectionViewDelegate 22 | 23 | @optional 24 | - (nonnull id)qmui_collectionView:(nonnull UICollectionView *)collectionView cacheKeyForItemAtIndexPath:(nonnull NSIndexPath *)indexPath; 25 | @end 26 | 27 | /// 注意,这个类的功能暂无法使用 28 | @interface UICollectionView (QMUICellSizeKeyCache) 29 | 30 | /// 控制是否要自动缓存 cell 的高度,默认为 NO 31 | @property(nonatomic, assign) BOOL qmui_cacheCellSizeByKeyAutomatically; 32 | 33 | /// 获取当前的缓存容器。tableView 的宽度和 contentInset 发生变化时,这个数组也会跟着变,但当 tableView 宽度小于 0 时会返回 nil。 34 | @property(nonatomic, weak, readonly, nullable) QMUICellSizeKeyCache *qmui_currentCellSizeKeyCache; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUICheckbox.h: -------------------------------------------------------------------------------- 1 | // 2 | // QMUICheckbox.h 3 | // QMUIKit 4 | // 5 | // Created by molice on 2024/8/1. 6 | // Copyright © 2024 QMUI Team. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "QMUIButton.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | /// 圆形勾选控件,selected = YES 表示勾选,indeterminate = YES 表示半选,enabled = NO 表示禁用。 15 | /// 由于父类是 QMUIButton,所以可以通过 setTitle:forState: 轻松实现左边 checkbox 右边说明文本的效果。 16 | /// 尺寸可以通过 checkboxSize 修改,颜色可通过 tintColor 修改。 17 | /// 点击勾选的交互需要由业务自己实现。 18 | @interface QMUICheckbox : QMUIButton 19 | 20 | /// 置为半选状态。可以理解为一个 Checkbox 的 indeterminate 和 checked(selected) 是平级的、互斥的,当该属性被设置为 YES 时,会将 selected 置为 NO,当 selected 被置为 YES 时,会将该属性置为 NO。 21 | @property(nonatomic, assign) BOOL indeterminate; 22 | 23 | /// 指定 checkbox 图片的尺寸(如果存在 title,不影响 title 的尺寸) 24 | /// 默认为(16, 16) 25 | @property(nonatomic, assign) CGSize checkboxSize; 26 | 27 | /// 未勾选的状态,置为 nil 则使用组件默认图 28 | @property(nonatomic, strong) UIImage *normalImage; 29 | 30 | /// 勾选的状态,置为 nil 则使用组件默认图 31 | @property(nonatomic, strong) UIImage *selectedImage; 32 | 33 | /// 半勾选的状态,置为 nil 则使用组件默认图 34 | @property(nonatomic, strong) UIImage *indeterminateImage; 35 | 36 | /// 未勾选且禁用的状态(如果是已勾选的禁用,会直接沿用该状态的图片,只有未勾选的禁用可以有单独的图),置为 nil 则使用组件默认图 37 | @property(nonatomic, strong) UIImage *disabledImage; 38 | @end 39 | 40 | NS_ASSUME_NONNULL_END 41 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIConsole/QMUIConsoleToolbar.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUIConsoleToolbar.h 11 | // QMUIKit 12 | // 13 | // Created by MoLice on 2019/J/11. 14 | // 15 | 16 | #import 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @class QMUIButton; 21 | @class QMUITextField; 22 | 23 | @interface QMUIConsoleToolbar : UIView 24 | 25 | @property(nonatomic, strong, readonly) QMUIButton *levelButton; 26 | @property(nonatomic, strong, readonly) QMUIButton *nameButton; 27 | @property(nonatomic, strong, readonly) QMUIButton *clearButton; 28 | @property(nonatomic, strong, readonly) QMUITextField *searchTextField; 29 | @property(nonatomic, strong, readonly) UILabel *searchResultCountLabel; 30 | @property(nonatomic, strong, readonly) QMUIButton *searchResultPreviousButton; 31 | @property(nonatomic, strong, readonly) QMUIButton *searchResultNextButton; 32 | 33 | - (void)setNeedsLayoutSearchResultViews; 34 | @end 35 | 36 | NS_ASSUME_NONNULL_END 37 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIConsole/QMUIConsoleViewController.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // QMUIConsoleViewController.h 10 | // QMUIKit 11 | // 12 | // Created by MoLice on 2019/J/11. 13 | // 14 | 15 | #import 16 | #import 17 | #import "QMUICommonViewController.h" 18 | 19 | NS_ASSUME_NONNULL_BEGIN 20 | 21 | @class QMUIButton; 22 | @class QMUITableView; 23 | @class QMUIConsoleToolbar; 24 | 25 | @interface QMUIConsoleViewController : QMUICommonViewController 26 | 27 | @property(nonatomic, strong, readonly) QMUIButton *popoverButton; 28 | @property(nonatomic, strong, readonly) QMUITableView *tableView; 29 | @property(nonatomic, strong, readonly) QMUIConsoleToolbar *toolbar; 30 | @property(nonatomic, strong, readonly) NSDateFormatter *dateFormatter; 31 | 32 | @property(nonatomic, strong) UIColor *backgroundColor; 33 | 34 | - (void)logWithLevel:(nullable NSString *)level name:(nullable NSString *)name logString:(id)logString; 35 | - (void)log:(id)logString; 36 | - (void)clear; 37 | @end 38 | 39 | NS_ASSUME_NONNULL_END 40 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIConsole/QMUILog+QMUIConsole.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUILog+QMUIConsole.h 11 | // QMUIKit 12 | // 13 | // Created by MoLice on 2019/J/15. 14 | // 15 | 16 | #import "QMUILog.h" 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @interface QMUILogger (QMUIConsole) 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIFloatLayoutView.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUIFloatLayoutView.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 2016/11/10. 14 | // 15 | 16 | #import 17 | 18 | /// 用于属性 maximumItemSize,是它的默认值。表示 item 的最大宽高会自动根据当前 floatLayoutView 的内容大小来调整,从而避免 item 内容过多时可能溢出 floatLayoutView。 19 | extern const CGSize QMUIFloatLayoutViewAutomaticalMaximumItemSize; 20 | 21 | /** 22 | * 做类似 CSS 里的 float:left 的布局,自行使用 addSubview: 将子 View 添加进来即可。 23 | * 24 | * 支持通过 `contentMode` 属性修改子 View 的对齐方式,目前仅支持 `UIViewContentModeLeft` 和 `UIViewContentModeRight`,默认为 `UIViewContentModeLeft`。 25 | */ 26 | @interface QMUIFloatLayoutView : UIView 27 | 28 | /** 29 | * QMUIFloatLayoutView 内部的间距,默认为 UIEdgeInsetsZero 30 | */ 31 | @property(nonatomic, assign) UIEdgeInsets padding; 32 | 33 | /** 34 | * item 的最小宽高,默认为 CGSizeZero,也即不限制。 35 | */ 36 | @property(nonatomic, assign) IBInspectable CGSize minimumItemSize; 37 | 38 | /** 39 | * item 的最大宽高,默认为 QMUIFloatLayoutViewAutomaticalMaximumItemSize,也即不超过 floatLayoutView 自身最大内容宽高。 40 | */ 41 | @property(nonatomic, assign) IBInspectable CGSize maximumItemSize; 42 | 43 | /** 44 | * item 之间的间距,默认为 UIEdgeInsetsZero。 45 | * 46 | * @warning 上、下、左、右四个边缘的 item 布局时不会考虑 itemMargins.top/bottom/left/right。 47 | */ 48 | @property(nonatomic, assign) UIEdgeInsets itemMargins; 49 | @end 50 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIGridView.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUIGridView.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 15/1/30. 14 | // 15 | 16 | #import 17 | 18 | /** 19 | * 用于做九宫格布局,会将内部所有的 subview 根据指定的列数和行高,把每个 item(也即 subview) 拉伸到相同的大小。 20 | * 21 | * 支持在 item 和 item 之间显示分隔线,分隔线支持虚线。 22 | * 23 | * @warning 注意分隔线是占位的,把 item 隔开,而不是盖在某个 item 上。 24 | */ 25 | @interface QMUIGridView : UIView 26 | 27 | /// 指定要显示的列数,默认为 0 28 | @property(nonatomic, assign) IBInspectable NSInteger columnCount; 29 | 30 | /// 指定每一行的高度,默认为 0 31 | @property(nonatomic, assign) IBInspectable CGFloat rowHeight; 32 | 33 | /// 内部的 padding,默认为 UIEdgeInsetsZero 34 | @property(nonatomic, assign) UIEdgeInsets padding; 35 | 36 | /// 指定 item 之间的分隔线宽度,默认为 0 37 | @property(nonatomic, assign) IBInspectable CGFloat separatorWidth; 38 | 39 | /// 指定 item 之间的分隔线颜色,默认为 UIColorSeparator 40 | @property(nonatomic, strong) IBInspectable UIColor *separatorColor; 41 | 42 | /// item 之间的分隔线是否要用虚线显示,默认为 NO 43 | @property(nonatomic, assign) IBInspectable BOOL separatorDashed; 44 | 45 | /// 候选的初始化方法,亦可通过 initWithFrame:、init 来初始化。 46 | - (instancetype)initWithColumn:(NSInteger)column rowHeight:(CGFloat)rowHeight; 47 | @end 48 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUILabel.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUILabel.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 14-7-3. 14 | // 15 | 16 | #import 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | /** 21 | * `QMUILabel`支持通过`contentEdgeInsets`属性来实现类似padding的效果。 22 | * 23 | * 同时通过将`canPerformCopyAction`置为`YES`来开启长按复制文本的功能,复制 item 的文案可通过 menuItemTitleForCopyAction 修改,长按时label的背景色默认为`highlightedBackgroundColor` 24 | */ 25 | @interface QMUILabel : UILabel 26 | 27 | /// 控制label内容的padding,默认为UIEdgeInsetsZero 28 | @property(nonatomic,assign) UIEdgeInsets contentEdgeInsets; 29 | 30 | /// 支持在 label 无法显示完整文字时在 label 的末尾显示一个自定义的 View(通常用来实现点击展开更多的交互) 31 | @property(nonatomic, strong, nullable) __kindof UIView *truncatingTailView; 32 | 33 | /// 是否需要长按复制的功能,默认为 NO。 34 | /// 长按时的背景色通过`highlightedBackgroundColor`设置。 35 | @property(nonatomic,assign) IBInspectable BOOL canPerformCopyAction; 36 | 37 | /// 当 canPerformCopyAction 开启时,长按出来的菜单上的复制按钮的文本,默认为 nil,nil 时 menuItem 上的文字为“复制” 38 | @property(nonatomic, copy, nullable) IBInspectable NSString *menuItemTitleForCopyAction; 39 | 40 | /** 41 | label 在 highlighted 时的背景色,通常用于两种场景: 42 | 1. 开启了 canPerformCopyAction 时,长按后的背景色 43 | 2. 作为 subviews 放在 UITableViewCell 上,当 cell highlighted 时,label 也会触发 highlighted,此时背景色也会显示为这个属性的值 44 | 45 | 默认为 nil 46 | */ 47 | @property(nonatomic,strong, nullable) IBInspectable UIColor *highlightedBackgroundColor UI_APPEARANCE_SELECTOR; 48 | 49 | /// 点击了“复制”后的回调 50 | @property(nonatomic, copy, nullable) void (^didCopyBlock)(QMUILabel *label, NSString *stringCopied); 51 | 52 | @end 53 | 54 | NS_ASSUME_NONNULL_END 55 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUILayouter/QMUILayouter.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUILayouter.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2024/1/2. 14 | // 15 | 16 | #import 17 | #import 18 | #import "QMUILayouterLinearHorizontal.h" 19 | #import "QMUILayouterLinearVertical.h" 20 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUILayouter/QMUILayouterLinearHorizontal.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUILayouterLinearHorizontal.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2024/1/2. 14 | // 15 | 16 | #import 17 | #import 18 | #import "QMUILayouterItem.h" 19 | 20 | NS_ASSUME_NONNULL_BEGIN 21 | 22 | /** 23 | 水平方向的线性布局,若容器大小不足以容纳所有 item,则末尾的 item 大小会被强制裁剪以保证不溢出。 24 | 子元素可通过设置自己的 grow 来达到撑满容器的效果。 25 | */ 26 | @interface QMUILayouterLinearHorizontal : QMUILayouterItem 27 | 28 | + (instancetype)itemWithChildItems:(NSArray *)childItems 29 | spacingBetweenItems:(CGFloat)spacingBetweenItems; 30 | 31 | + (instancetype)itemWithChildItems:(NSArray *)childItems 32 | spacingBetweenItems:(CGFloat)spacingBetweenItems 33 | horizontal:(QMUILayouterAlignment)horizontal 34 | vertical:(QMUILayouterAlignment)vertical; 35 | 36 | /// 子元素之间的间距 37 | @property(nonatomic, assign) CGFloat spacingBetweenItems; 38 | 39 | /// 子元素水平方向上的布局方式,默认为 QMUILayouterAlignmentLeading,每种 enum 的布局说明请查看 enum 定义。 40 | @property(nonatomic, assign) QMUILayouterAlignment childHorizontalAlignment; 41 | 42 | /// 子元素竖直方向上的布局方式,默认为 QMUILayouterAlignmentLeading,每种 enum 的布局说明请查看 enum 定义。 43 | @property(nonatomic, assign) QMUILayouterAlignment childVerticalAlignment; 44 | @end 45 | 46 | NS_ASSUME_NONNULL_END 47 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUILayouter/QMUILayouterLinearVertical.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUILayouterLinearVertical.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2024/1/2. 14 | // 15 | 16 | #import 17 | #import 18 | #import "QMUILayouterItem.h" 19 | 20 | NS_ASSUME_NONNULL_BEGIN 21 | 22 | /** 23 | 竖直方向的线性布局,若容器大小不足以容纳所有 item,则末尾的 item 大小会被强制裁剪以保证不溢出。 24 | 子元素可通过设置自己的 grow 来达到撑满容器的效果。 25 | */ 26 | @interface QMUILayouterLinearVertical : QMUILayouterItem 27 | 28 | + (instancetype)itemWithChildItems:(NSArray *)childItems 29 | spacingBetweenItems:(CGFloat)spacingBetweenItems; 30 | 31 | + (instancetype)itemWithChildItems:(NSArray *)childItems 32 | spacingBetweenItems:(CGFloat)spacingBetweenItems 33 | horizontal:(QMUILayouterAlignment)horizontal 34 | vertical:(QMUILayouterAlignment)vertical; 35 | 36 | /// 子元素之间的间距 37 | @property(nonatomic, assign) CGFloat spacingBetweenItems; 38 | 39 | /// 子元素水平方向上的布局方式,默认为 QMUILayouterAlignmentLeading,每种 enum 的布局说明请查看 enum 定义。 40 | @property(nonatomic, assign) QMUILayouterAlignment childHorizontalAlignment; 41 | 42 | /// 子元素竖直方向上的布局方式,默认为 QMUILayouterAlignmentLeading,每种 enum 的布局说明请查看 enum 定义。 43 | @property(nonatomic, assign) QMUILayouterAlignment childVerticalAlignment; 44 | @end 45 | 46 | NS_ASSUME_NONNULL_END 47 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUILog/QMUILog.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUILog.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/1/22. 14 | // 15 | 16 | #import 17 | #import "QMUILogItem.h" 18 | #import "QMUILogNameManager.h" 19 | #import "QMUILogger.h" 20 | #import 21 | 22 | /// 以下是 QMUI 提供的用于代替 NSLog() 的打 log 的方法,可根据 logName、logLevel 两个维度来控制某些 log 是否要被打印,以便在调试时去掉不关注的 log。 23 | 24 | #define QMUILog(_name, ...) [[QMUILogger sharedInstance] printLogWithFile:__FILE__ line:__LINE__ func:__FUNCTION__ logItem:[QMUILogItem logItemWithLevel:QMUILogLevelDefault name:_name logString:__VA_ARGS__]] 25 | #define QMUILogInfo(_name, ...) [[QMUILogger sharedInstance] printLogWithFile:__FILE__ line:__LINE__ func:__FUNCTION__ logItem:[QMUILogItem logItemWithLevel:QMUILogLevelInfo name:_name logString:__VA_ARGS__]] 26 | #define QMUILogWarn(_name, ...) [[QMUILogger sharedInstance] printLogWithFile:__FILE__ line:__LINE__ func:__FUNCTION__ logItem:[QMUILogItem logItemWithLevel:QMUILogLevelWarn name:_name logString:__VA_ARGS__]] 27 | 28 | //#ifdef DEBUG 29 | // 30 | //// iOS 11 之前用真正的方法替换去实现拦截 NSLog 的功能,iOS 11 之后这种方法失效了,所以只能用宏定义的方式覆盖 NSLog。这也就意味着在 iOS 11 下一些如果某些代码编译时机比 QMUI 早,则这些代码里的 NSLog 是无法被替换为 QMUILog 的 31 | //extern void _NSSetLogCStringFunction(void (*)(const char *string, unsigned length, BOOL withSyslogBanner)); 32 | //static void PrintNSLogMessage(const char *string, unsigned length, BOOL withSyslogBanner) { 33 | // QMUILog(@"NSLog", @"%s", string); 34 | //} 35 | // 36 | //static void HackNSLog(void) __attribute__((constructor)); 37 | //static void HackNSLog(void) { 38 | // _NSSetLogCStringFunction(PrintNSLogMessage); 39 | //} 40 | // 41 | //#define NSLog(...) QMUILog(@"NSLog", __VA_ARGS__)// iOS 11 以后真正生效的是这一句 42 | //#endif 43 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUILog/QMUILogItem.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUILogItem.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/1/24. 14 | // 15 | 16 | #import 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | typedef NS_ENUM(NSUInteger, QMUILogLevel) { 21 | QMUILogLevelDefault, // 当使用 QMUILog() 时使用的等级 22 | QMUILogLevelInfo, // 当使用 QMUILogInfo() 时使用的等级,比 QMUILogLevelDefault 要轻量,适用于一些无关紧要的信息 23 | QMUILogLevelWarn // 当使用 QMUILogWarn() 时使用的等级,最重,适用于一些异常或者严重错误的场景 24 | }; 25 | 26 | /// 每一条 QMUILog 日志都以 QMUILogItem 的形式包装起来 27 | @interface QMUILogItem : NSObject 28 | 29 | /// 日志的等级,可通过 QMUIConfigurationTemplate 配置表控制全局每个 level 是否可用 30 | @property(nonatomic, assign) QMUILogLevel level; 31 | @property(nonatomic, copy, readonly) NSString *levelDisplayString; 32 | 33 | /// 可利用 name 字段为日志分类,QMUILogNameManager 可全局控制某一个 name 是否可用 34 | @property(nullable, nonatomic, copy) NSString *name; 35 | 36 | /// 日志的内容 37 | @property(nonatomic, copy) NSString *logString; 38 | 39 | /// 当前 logItem 对应的 name 是否可用,可通过 QMUILogNameManager 控制,默认为 YES 40 | @property(nonatomic, assign) BOOL enabled; 41 | 42 | + (nonnull instancetype)logItemWithLevel:(QMUILogLevel)level name:(nullable NSString *)name logString:(nonnull NSString *)logString, ... NS_FORMAT_FUNCTION(3, 4); 43 | @end 44 | 45 | NS_ASSUME_NONNULL_END 46 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUILog/QMUILogItem.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUILogItem.m 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/1/24. 14 | // 15 | 16 | #import "QMUILogItem.h" 17 | #import "QMUILogger.h" 18 | #import "QMUILogNameManager.h" 19 | 20 | @implementation QMUILogItem 21 | 22 | + (instancetype)logItemWithLevel:(QMUILogLevel)level name:(NSString *)name logString:(NSString *)logString, ... { 23 | QMUILogItem *logItem = [[self alloc] init]; 24 | logItem.level = level; 25 | logItem.name = name; 26 | 27 | QMUILogNameManager *logNameManager = [QMUILogger sharedInstance].logNameManager; 28 | if ([logNameManager containsLogName:name]) { 29 | logItem.enabled = [logNameManager enabledForLogName:name]; 30 | } else { 31 | [logNameManager setEnabled:YES forLogName:name]; 32 | logItem.enabled = YES; 33 | } 34 | 35 | va_list args; 36 | va_start(args, logString); 37 | logItem.logString = [[NSString alloc] initWithFormat:logString arguments:args]; 38 | va_end(args); 39 | 40 | return logItem; 41 | } 42 | 43 | - (instancetype)init { 44 | if (self = [super init]) { 45 | self.enabled = YES; 46 | } 47 | return self; 48 | } 49 | 50 | - (NSString *)levelDisplayString { 51 | switch (self.level) { 52 | case QMUILogLevelInfo: 53 | return @"QMUILogLevelInfo"; 54 | case QMUILogLevelWarn: 55 | return @"QMUILogLevelWarn"; 56 | default: 57 | return @"QMUILogLevelDefault"; 58 | } 59 | } 60 | 61 | - (NSString *)description { 62 | return [NSString stringWithFormat:@"%@ | %@ | %@", self.levelDisplayString, self.name.length > 0 ? self.name : @"Default", self.logString]; 63 | } 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUILog/QMUILogNameManager.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUILogNameManager.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/1/24. 14 | // 15 | 16 | #import 17 | 18 | /// 所有 QMUILog 的 name 都会以这个 key 存储到 NSUserDefaults 里(类型为 NSDictionary *),可通过 dictionaryForKey: 获取到所有的 name 及对应的 enabled 状态。 19 | extern NSString * _Nonnull const QMUILoggerAllNamesKeyInUserDefaults; 20 | 21 | /// log.name 的管理器,由它来管理每一个 name 是否可用、以及清理不需要的 name 22 | @interface QMUILogNameManager : NSObject 23 | 24 | /// 获取当前所有 logName,key 为 logName 名,value 为 name 的 enabled 状态,可通过 value.boolValue 读取它的值 25 | @property(nullable, nonatomic, copy, readonly) NSDictionary *allNames; 26 | - (BOOL)containsLogName:(nullable NSString *)logName; 27 | - (void)setEnabled:(BOOL)enabled forLogName:(nullable NSString *)logName; 28 | - (BOOL)enabledForLogName:(nullable NSString *)logName; 29 | - (void)removeLogName:(nullable NSString *)logName; 30 | - (void)removeAllNames; 31 | @end 32 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUILog/QMUILogger.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // QMUILogger.h 10 | // QMUIKit 11 | // 12 | // Created by QMUI Team on 2018/1/24. 13 | // 14 | #import 15 | 16 | @class QMUILogNameManager; 17 | @class QMUILogItem; 18 | 19 | @protocol QMUILoggerDelegate 20 | 21 | @optional 22 | 23 | /** 24 | * 当每一个 enabled 的 QMUILog 被使用时都会走到这里,可以由业务自行决定要如何处理这些 log,如果没实现这个方法,默认用 NSLog() 打印内容 25 | * @param file 当前的文件的本地完整路径,可通过 file.lastPathComponent 获取文件名 26 | * @param line 当前 log 命令在该文件里的代码行数 27 | * @param func 当前 log 命令所在的方法名 28 | * @param logItem 当前 log 命令对应的 QMUILogItem,可得知该 log 的 level 29 | * @param defaultString QMUI 默认拼好的 log 内容 30 | */ 31 | - (void)printQMUILogWithFile:(nonnull NSString *)file line:(int)line func:(nullable NSString *)func logItem:(nullable QMUILogItem *)logItem defaultString:(nullable NSString *)defaultString; 32 | 33 | /** 34 | * 当某个 logName 的 enabled 发生变化时,通知到 delegate。注意如果是新创建某个 logName 也会走到这里。 35 | * @param logName 变化的 logName 36 | * @param enabled 变化后的值 37 | */ 38 | - (void)QMUILogName:(nonnull NSString *)logName didChangeEnabled:(BOOL)enabled; 39 | 40 | /** 41 | * 某个 logName 被删除时通知到 delegate 42 | * @param logName 被删除的 logName 43 | */ 44 | - (void)QMUILogNameDidRemove:(nonnull NSString *)logName; 45 | 46 | @end 47 | 48 | @interface QMUILogger : NSObject 49 | 50 | @property(nullable, nonatomic, weak) id delegate; 51 | @property(nonnull, nonatomic, strong) QMUILogNameManager *logNameManager; 52 | 53 | + (nonnull instancetype)sharedInstance; 54 | - (void)printLogWithFile:(nullable const char *)file line:(int)line func:(nonnull const char *)func logItem:(nullable QMUILogItem *)logItem; 55 | @end 56 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUILogManagerViewController.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUILogManagerViewController.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/1/24. 14 | // 15 | 16 | #import "QMUICommonTableViewController.h" 17 | 18 | /// 用于管理 QMUILog name 的调试界面,可直接 init 使用 19 | @interface QMUILogManagerViewController : QMUICommonTableViewController 20 | 21 | /// cell 总个数大于等于这个数值时才会出搜索框和右边的 section title 索引条,方便检索。默认值为 10。 22 | @property(nonatomic, assign) NSUInteger rowCountWhenShowSearchBar; 23 | 24 | /// 一般项目的 logName 都会带有统一前缀(例如 @"QMUIImagePickerLibrary"),而在排序的时候,前缀通常是无意义的,因此这里提供一个 block 让你可以根据传进去的 logName 返回一个不带前缀的用于排序的 logName,且这个返回值的第一个字母将会作为 section 的索引显示在列表右边。若不实现这个 block 则直接拿原 logName 进行排序。 25 | @property(nonatomic, copy) NSString *(^formatLogNameForSortingBlock)(NSString *logName); 26 | 27 | /// 可自定义 cell 的文字样式,方便区分不同的 logName 28 | @property(nonatomic, copy) NSAttributedString *(^formatCellTextBlock)(NSString *logName); 29 | @end 30 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUILogger+QMUIConfigurationTemplate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUILogger+QMUIConfigurationTemplate.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/7/28. 14 | // 15 | 16 | #import 17 | #import "QMUILog.h" 18 | 19 | @interface QMUILogger (QMUIConfigurationTemplate) 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUILogger+QMUIConfigurationTemplate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUILogger+QMUIConfigurationTemplate.m 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/7/28. 14 | // 15 | 16 | #import "QMUILogger+QMUIConfigurationTemplate.h" 17 | #import "QMUICore.h" 18 | 19 | @implementation QMUILogger (QMUIConfigurationTemplate) 20 | 21 | + (void)load { 22 | static dispatch_once_t onceToken; 23 | dispatch_once(&onceToken, ^{ 24 | OverrideImplementation([QMUILogger class], @selector(printLogWithFile:line:func:logItem:), ^id(__unsafe_unretained Class originClass, SEL originCMD, IMP (^originalIMPProvider)(void)) { 25 | return ^(QMUILogger *selfObject, const char *file, int line, const char *func, QMUILogItem *logItem) { 26 | // 不同级别的 log 可通过配置表的开关来控制是否要输出 27 | if (logItem.level == QMUILogLevelDefault && !ShouldPrintDefaultLog) return; 28 | if (logItem.level == QMUILogLevelInfo && !ShouldPrintInfoLog) return; 29 | if (logItem.level == QMUILogLevelWarn && !ShouldPrintWarnLog) return; 30 | 31 | // call super 32 | void (*originSelectorIMP)(id, SEL, const char *, int, const char *, QMUILogItem *); 33 | originSelectorIMP = (void (*)(id, SEL, const char *, int, const char *, QMUILogItem *))originalIMPProvider(); 34 | originSelectorIMP(selfObject, originCMD, file, line, func, logItem); 35 | }; 36 | }); 37 | }); 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIMultipleDelegates/NSObject+QMUIMultipleDelegates.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // NSObject+MultipleDelegates.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/3/27. 14 | // 15 | 16 | #import 17 | 18 | @class QMUIMultipleDelegates; 19 | 20 | /** 21 | * 让所有 NSObject 都支持多个 delegate,默认只支持属性名为 delegate 的 delegate(特别地,UITableView 和 UICollectionView 额外默认支持 dataSource)。 22 | * 使用方式:将 qmui_multipleDelegatesEnabled 置为 YES 后像平时一样 self.delegate = xxx 即可。 23 | * 如果你要清掉所有的 delegate,则像平时一样 self.delegate = nil 即可。 24 | * 如果你把 delegate 同时赋值给 objA 和 objB,而你只要移除 objB,则可:[self qmui_removeDelegate:objB] 25 | * 26 | * 如果你要让其他命名的 delegate 属性也支持多 delegate,则可调用 qmui_registerDelegateSelector: 方法将该属性的 getter 传进去,再进行实际的 delegate 赋值,例如你的 delegate 命名为 abcDelegate,则你可以这么写: 27 | * [self qmui_registerDelegateSelector:@selector(abcDelegate)]; 28 | * self.abcDelegate = delegateA; 29 | * self.abcDelegate = delegateB; 30 | * 31 | * @warning 不支持 self.delegate = self 的写法,会引发死循环,有这种需求的场景建议在 self 内部创建一个对象专门用于 delegate 的响应,参考 _QMUITextViewDelegator。 32 | */ 33 | @interface NSObject (QMUIMultipleDelegates) 34 | 35 | /// 当你需要当前的 class 支持多个 delegate,请将此属性置为 YES。默认为 NO。 36 | @property(nonatomic, assign) BOOL qmui_multipleDelegatesEnabled; 37 | 38 | /// 让某个 delegate 属性也支持多 delegate 模式(默认只帮你加了 @selector(delegate) 的支持,如果有其他命名的 property 就需要自己用这个方法添加) 39 | - (void)qmui_registerDelegateSelector:(SEL)getter; 40 | 41 | /// 移除某个特定的 delegate 对象,例如假设你把 delegate 同时赋值给 objA 和 objB,而你只要移除 objB,则可:[self qmui_removeDelegate:objB]。但如果你想同时移除 objA 和 objB(也即全部 delegate),则像往常一样直接 self.delegate = nil 即可。 42 | - (void)qmui_removeDelegate:(id)delegate; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIMultipleDelegates/QMUIMultipleDelegates.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUIMultipleDelegates.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/3/27. 14 | // 15 | 16 | #import 17 | #import 18 | #import "NSObject+QMUIMultipleDelegates.h" 19 | 20 | /// 存放多个 delegate 指针的容器,必须搭配其他控件使用,一般不需要你自己 init。作用是让某个 class 支持同时存在多个 delegate。更多说明请查看 NSObject (QMUIMultipleDelegates) 的注释。 21 | @interface QMUIMultipleDelegates : NSObject 22 | 23 | + (instancetype)weakDelegates; 24 | + (instancetype)strongDelegates; 25 | 26 | @property(nonatomic, strong, readonly) NSPointerArray *delegates; 27 | @property(nonatomic, weak) NSObject *parentObject; 28 | 29 | - (void)addDelegate:(id)delegate; 30 | - (BOOL)removeDelegate:(id)delegate; 31 | - (void)removeAllDelegates; 32 | - (BOOL)containsDelegate:(id)delegate; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIOrderedDictionary.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUIOrderedDictionary.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 16/7/21. 14 | // 15 | 16 | #import 17 | #import 18 | 19 | NS_ASSUME_NONNULL_BEGIN 20 | 21 | /** 22 | 一个简单实现的有序的 key-value 容器,通过 initWithKeysAndObjects: 初始化后,用下标访问即可,如 dict[0] 或 dict[key] 23 | */ 24 | @interface QMUIOrderedDictionary<__covariant KeyType, __covariant ObjectType> : NSObject 25 | 26 | - (instancetype)initWithKeysAndObjects:(id)firstKey,...; 27 | 28 | @property(readonly) NSUInteger count; 29 | @property(nonatomic, copy, readonly) NSArray *allKeys; 30 | @property(nonatomic, copy, readonly) NSArray *allValues; 31 | - (void)setObject:(ObjectType)object forKey:(KeyType)key; 32 | - (void)addObject:(ObjectType)object forKey:(KeyType)key; 33 | - (void)addObjects:(NSArray *)objects forKeys:(NSArray *)keys; 34 | - (void)insertObject:(ObjectType)object forKey:(KeyType)key atIndex:(NSInteger)index; 35 | - (void)insertObjects:(NSArray *)objects forKeys:(NSArray *)keys atIndex:(NSInteger)index; 36 | - (void)removeObject:(ObjectType)object forKey:(KeyType)key; 37 | - (void)removeObject:(ObjectType)object atIndex:(NSInteger)index; 38 | - (nullable ObjectType)objectForKey:(KeyType)key; 39 | - (ObjectType)objectAtIndex:(NSInteger)index; 40 | 41 | // 支持下标的方式访问,需要声明以下两个方法 42 | - (nullable ObjectType)objectForKeyedSubscript:(KeyType)key; 43 | - (ObjectType)objectAtIndexedSubscript:(NSUInteger)idx; 44 | 45 | @end 46 | 47 | NS_ASSUME_NONNULL_END 48 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIPieProgressView.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUIPieProgressView.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 15/9/8. 14 | // 15 | 16 | #import 17 | 18 | /** 19 | * 饼状进度条控件 20 | * 21 | * 使用 `tintColor` 更改进度条饼状部分和边框部分的颜色 22 | * 23 | * 使用 `backgroundColor` 更改圆形背景色 24 | * 25 | * 通过 `UIControlEventValueChanged` 来监听进度变化 26 | */ 27 | 28 | typedef NS_ENUM(NSUInteger, QMUIPieProgressViewShape) { 29 | QMUIPieProgressViewShapeSector, // 扇形,默认 30 | QMUIPieProgressViewShapeRing // 环形 31 | }; 32 | 33 | @interface QMUIPieProgressView : UIControl 34 | 35 | /** 36 | 进度动画的时长,默认为 0.5 37 | */ 38 | @property(nonatomic, assign) IBInspectable CFTimeInterval progressAnimationDuration; 39 | 40 | /** 41 | 当前进度值,默认为 0.0。调用 `setProgress:` 相当于调用 `setProgress:animated:NO` 42 | */ 43 | @property(nonatomic, assign) IBInspectable float progress; 44 | 45 | /** 46 | 外边框的大小,默认为 1。 47 | */ 48 | @property(nonatomic, assign) IBInspectable CGFloat borderWidth; 49 | 50 | /** 51 | 外边框与内部扇形之间的间隙,默认为 0。 52 | */ 53 | @property(nonatomic, assign) IBInspectable CGFloat borderInset; 54 | 55 | /** 56 | 线宽,用于环形绘制,默认为 0。 57 | */ 58 | @property(nonatomic, assign) IBInspectable CGFloat lineWidth; 59 | 60 | /** 61 | 绘制形状,默认是扇形。 62 | */ 63 | @property(nonatomic, assign) IBInspectable QMUIPieProgressViewShape shape; 64 | 65 | /** 66 | 修改当前的进度,会触发 UIControlEventValueChanged 事件 67 | 68 | @param progress 当前的进度,取值范围 [0.0-1.0] 69 | @param animated 是否以动画来表现 70 | */ 71 | - (void)setProgress:(float)progress animated:(BOOL)animated; 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIPopupMenuView/QMUIPopupMenuItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // QMUIPopupMenuItem.m 3 | // QMUIKit 4 | // 5 | // Created by molice on 2024/6/17. 6 | // Copyright © 2024 QMUI Team. All rights reserved. 7 | // 8 | 9 | #import "QMUIPopupMenuItem.h" 10 | 11 | @implementation QMUIPopupMenuItem 12 | 13 | - (instancetype)init { 14 | self = [super init]; 15 | if (self) { 16 | _height = -1; 17 | } 18 | return self; 19 | } 20 | 21 | + (instancetype)itemWithImage:(UIImage *)image title:(NSString *)title subtitle:(NSString *)subtitle handler:(void (^ _Nullable)(__kindof QMUIPopupMenuItem * _Nonnull, __kindof UIControl * _Nonnull, NSInteger, NSInteger))handler { 22 | QMUIPopupMenuItem *item = [[self alloc] init]; 23 | item.image = image; 24 | item.title = title; 25 | item.subtitle = subtitle; 26 | item.handler = handler; 27 | return item; 28 | } 29 | 30 | + (instancetype)itemWithTitle:(NSString *)title handler:(void (^ _Nullable)(__kindof QMUIPopupMenuItem * _Nonnull, __kindof UIControl * _Nonnull, NSInteger, NSInteger))handler { 31 | return [self itemWithImage:nil title:title subtitle:nil handler:handler]; 32 | } 33 | 34 | + (instancetype)itemWithImage:(UIImage *)image title:(NSString *)title handler:(void (^ _Nullable)(__kindof QMUIPopupMenuItem * _Nonnull, __kindof UIControl * _Nonnull, NSInteger, NSInteger))handler { 35 | return [self itemWithImage:image title:title subtitle:nil handler:handler]; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIPopupMenuView/QMUIPopupMenuItemView.h: -------------------------------------------------------------------------------- 1 | // 2 | // QMUIPopupMenuItemView.h 3 | // QMUIKit 4 | // 5 | // Created by molice on 2024/6/17. 6 | // Copyright © 2024 QMUI Team. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "QMUIPopupMenuItemViewProtocol.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @class QMUIButton; 15 | @class QMUICheckbox; 16 | 17 | @interface QMUIPopupMenuItemView : UIControl 18 | 19 | /// 图片、文本、第二行文本所在的 view,不接受事件,点击事件由 self 接管。 20 | @property(nonatomic, strong, readonly) QMUIButton *button; 21 | 22 | /// 当菜单进入选择模式时,代表被选中的勾。非选择模式时不存在。 23 | @property(nonatomic, strong, readonly, nullable) UIImageView *checkmark; 24 | 25 | /// 当菜单进入选择模式时,代表被选中的圆形勾,不接受事件,勾选状态由菜单控制。非选择模式时不存在。 26 | @property(nonatomic, strong, readonly, nullable) QMUICheckbox *checkbox; 27 | 28 | @property(nonatomic, strong, nullable) UIColor *highlightedBackgroundColor; 29 | 30 | @property(nonatomic, assign) UIEdgeInsets padding; 31 | @property(nonatomic, assign) CGFloat spacingBetweenButtonAndCheck; 32 | @end 33 | 34 | NS_ASSUME_NONNULL_END 35 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIPopupMenuView/QMUIPopupMenuItemViewProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // QMUIPopupMenuItemViewProtocol.h 3 | // QMUIKit 4 | // 5 | // Created by molice on 2024/6/17. 6 | // Copyright © 2024 QMUI Team. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @class QMUIPopupMenuItem; 14 | 15 | @protocol QMUIPopupMenuItemViewProtocol 16 | 17 | @required 18 | 19 | /// 当前 itemView 关联的 item,在 cellForRow 时会被设置。itemView 内所有与 item 强相关的内容均应在 setItem: 方法里设置。 20 | @property(nonatomic, weak, nullable) __kindof QMUIPopupMenuItem *item; 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIScrollAnimator/QMUIScrollAnimator.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUIScrollAnimator.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/S/30. 14 | // 15 | 16 | #import 17 | #import 18 | 19 | NS_ASSUME_NONNULL_BEGIN 20 | 21 | /** 22 | 一个方便地监控 UIScrollView 滚动的类,可在 didScrollBlock 里做一些与滚动位置相关的事情。 23 | 24 | 使用方式: 25 | 1. 用 init 初始化。 26 | 2. 通过 scrollView 绑定一个 UIScrollView。 27 | 3. 在 didScrollBlock 里做一些与滚动位置相关的事情。 28 | */ 29 | @interface QMUIScrollAnimator : NSObject 30 | 31 | /// 绑定的 UIScrollView 32 | @property(nullable, nonatomic, weak) __kindof UIScrollView *scrollView; 33 | 34 | /// UIScrollView 滚动时会调用这个 block 35 | @property(nonatomic, copy) void (^didScrollBlock)(__kindof QMUIScrollAnimator *animator); 36 | 37 | /// 当 enabled 为 NO 时,即便 scrollView 滚动,didScrollBlock 也不会被调用。默认为 YES。 38 | @property(nonatomic, assign) BOOL enabled; 39 | 40 | /// 立即根据当前的滚动位置更新状态 41 | - (void)updateScroll; 42 | 43 | @end 44 | 45 | NS_ASSUME_NONNULL_END 46 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUISearchBar.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUISearchBar.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 14-7-2. 14 | // 15 | 16 | #import 17 | 18 | @interface QMUISearchBar : UISearchBar 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUISearchBar.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUISearchBar.m 11 | // qmui 12 | // 13 | // Created by QMUI Team on 14-7-2. 14 | // 15 | 16 | #import "QMUISearchBar.h" 17 | #import "UISearchBar+QMUI.h" 18 | 19 | @implementation QMUISearchBar 20 | 21 | - (instancetype)initWithFrame:(CGRect)frame { 22 | if (self = [super initWithFrame:frame]) { 23 | [self didInitialize]; 24 | } 25 | return self; 26 | } 27 | 28 | - (instancetype)initWithCoder:(NSCoder *)coder { 29 | self = [super initWithCoder:coder]; 30 | if (self) { 31 | [self didInitialize]; 32 | } 33 | return self; 34 | } 35 | 36 | - (void)didInitialize { 37 | [self qmui_styledAsQMUISearchBar]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUISheetPresentation/QMUISheetPresentationNavigationBar.h: -------------------------------------------------------------------------------- 1 | // 2 | // QMUISheetPresentationNavigationBar.h 3 | // QMUIKit 4 | // 5 | // Created by molice on 2024/2/27. 6 | // Copyright © 2024 QMUI Team. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface QMUISheetPresentationNavigationBar : UIView 14 | 15 | @property(nonatomic, strong, nullable) UINavigationItem *navigationItem; 16 | 17 | @property(nonatomic, strong) UILabel *titleLabel; 18 | @property(nonatomic, strong) __kindof UIView *titleView; 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUISheetPresentation/QMUISheetPresentationNavigationBar.m: -------------------------------------------------------------------------------- 1 | // 2 | // QMUISheetPresentationNavigationBar.m 3 | // QMUIKit 4 | // 5 | // Created by molice on 2024/2/27. 6 | // Copyright © 2024 QMUI Team. All rights reserved. 7 | // 8 | 9 | #import "QMUISheetPresentationNavigationBar.h" 10 | #import "QMUICore.h" 11 | #import "QMUIButton.h" 12 | #import "QMUINavigationButton.h" 13 | 14 | @interface QMUISheetPresentationNavigationBar () 15 | @property(nonatomic, strong) QMUINavigationButton *backButton; 16 | @property(nonatomic, strong) QMUIButton *leftButton; 17 | @property(nonatomic, strong) QMUIButton *rightButton; 18 | @end 19 | 20 | @implementation QMUISheetPresentationNavigationBar 21 | 22 | - (instancetype)initWithFrame:(CGRect)frame { 23 | self = [super initWithFrame:frame]; 24 | if (self) { 25 | self.backgroundColor = UIColor.whiteColor; 26 | 27 | self.titleLabel = [[UILabel alloc] init]; 28 | if (QMUICMIActivated) { 29 | self.titleLabel.font = NavBarTitleFont; 30 | self.titleLabel.textColor = NavBarTitleColor; 31 | } 32 | } 33 | return self; 34 | } 35 | 36 | - (void)setNavigationItem:(UINavigationItem *)navigationItem { 37 | if (_navigationItem != navigationItem) { 38 | self.titleLabel.text = nil; 39 | [self.titleView removeFromSuperview]; 40 | } 41 | _navigationItem = navigationItem; 42 | if (navigationItem.titleView) { 43 | self.titleView = navigationItem.titleView; 44 | } else if (navigationItem.title.length) { 45 | self.titleLabel.text = navigationItem.title; 46 | self.titleView = self.titleLabel; 47 | } 48 | [self addSubview:self.titleView]; 49 | } 50 | 51 | - (CGSize)sizeThatFits:(CGSize)size { 52 | return CGSizeMake(size.width, 56); 53 | } 54 | 55 | - (void)layoutSubviews { 56 | [super layoutSubviews]; 57 | [self.titleView sizeToFit]; 58 | self.titleView.center = CGPointMake(CGRectGetWidth(self.bounds) / 2, CGRectGetHeight(self.bounds) / 2); 59 | } 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUITableView.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUITableView.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 14-7-2. 14 | // 15 | 16 | #import 17 | #import "QMUITableViewProtocols.h" 18 | 19 | @interface QMUITableView : UITableView 20 | 21 | @property(nonatomic, weak) id delegate; 22 | @property(nonatomic, weak) id dataSource; 23 | 24 | @end 25 | 26 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUITableView.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUITableView.m 11 | // qmui 12 | // 13 | // Created by QMUI Team on 14-7-2. 14 | // 15 | 16 | #import "QMUITableView.h" 17 | #import "UITableView+QMUI.h" 18 | #import "UIView+QMUI.h" 19 | 20 | @implementation QMUITableView 21 | 22 | @dynamic delegate; 23 | @dynamic dataSource; 24 | 25 | - (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style { 26 | if (self = [super initWithFrame:frame style:style]) { 27 | [self didInitialize]; 28 | } 29 | return self; 30 | } 31 | 32 | - (instancetype)initWithCoder:(NSCoder *)aDecoder { 33 | if (self = [super initWithCoder:aDecoder]) { 34 | [self didInitialize]; 35 | } 36 | return self; 37 | } 38 | 39 | - (void)didInitialize { 40 | [self qmui_styledAsQMUITableView]; 41 | } 42 | 43 | - (void)dealloc { 44 | self.dataSource = nil; 45 | self.delegate = nil; 46 | } 47 | 48 | // 保证一直存在tableFooterView,以去掉列表内容不满一屏时尾部的空白分割线 49 | - (void)setTableFooterView:(UIView *)tableFooterView { 50 | if (!tableFooterView) { 51 | tableFooterView = [[UIView alloc] init]; 52 | } 53 | [super setTableFooterView:tableFooterView]; 54 | } 55 | 56 | - (BOOL)touchesShouldCancelInContentView:(UIView *)view { 57 | if ([self.delegate respondsToSelector:@selector(tableView:touchesShouldCancelInContentView:)]) { 58 | return [self.delegate tableView:self touchesShouldCancelInContentView:view]; 59 | } 60 | // 默认情况下只有当view是非UIControl的时候才会返回yes,这里统一对UIButton也返回yes 61 | // 原因是UITableView上面把事件延迟去掉了,但是这样如果拖动的时候手指是在UIControl上面的话,就拖动不了了 62 | if ([view isKindOfClass:[UIControl class]]) { 63 | if ([view isKindOfClass:[UIButton class]]) { 64 | return YES; 65 | } else { 66 | return NO; 67 | } 68 | } 69 | return YES; 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUITableViewHeaderFooterView.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUITableViewHeaderFooterView.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2017/12/7. 14 | // 15 | 16 | #import 17 | 18 | typedef NS_ENUM(NSUInteger, QMUITableViewHeaderFooterViewType) { 19 | QMUITableViewHeaderFooterViewTypeUnknow, 20 | QMUITableViewHeaderFooterViewTypeHeader, 21 | QMUITableViewHeaderFooterViewTypeFooter 22 | }; 23 | 24 | /** 25 | * 适用于 UITableView 的 sectionHeaderFooterView,提供的特性包括: 26 | * 1. 支持单个 UILabel,该 label 支持多行文字。 27 | * 2. 支持右边添加一个 accessoryView(注意,设置 accessoryView 之前请先保证自身大小正确)。 28 | * 3. 支持调整 headerFooterView 的 padding。 29 | * 4. 支持应用配置表的样式。 30 | * 31 | * 使用方式: 32 | * 基本与系统的 UITableViewHeaderFooterView 使用方式一致,额外需要做的事情有: 33 | * 1. 如果要支持高度自动根据内容变化,则按系统的 self-sizing 方式,用 UITableViewAutomaticDimension 指定。或者重写 tableView:heightForHeaderInSection:、tableView:heightForFooterInSection:,在里面调用 headerFooterView 的 sizeThatFits:。 34 | * 2. 如果要应用配置表样式,则设置 parentTableView 和 type 这两个属性即可。特别的,QMUICommonTableViewController 里默认已经处理好 parentTableView 和 type,子类无需操作。 35 | */ 36 | @interface QMUITableViewHeaderFooterView : UITableViewHeaderFooterView 37 | 38 | @property(nonatomic, weak) UITableView *parentTableView; 39 | @property(nonatomic, assign) QMUITableViewHeaderFooterViewType type; 40 | 41 | @property(nonatomic, strong, readonly) UILabel *titleLabel; 42 | @property(nonatomic, strong) __kindof UIView *accessoryView; 43 | 44 | @property(nonatomic, assign) UIEdgeInsets contentEdgeInsets; 45 | @property(nonatomic, assign) UIEdgeInsets accessoryViewMargins; 46 | @end 47 | 48 | @interface QMUITableViewHeaderFooterView (UISubclassingHooks) 49 | 50 | /// 子类重写,用于修改样式,会在 parentTableView、type 属性发生变化的时候被调用 51 | - (void)updateAppearance; 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUITableViewProtocols.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUITableViewProtocols.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 2016/12/9. 14 | // 15 | 16 | #import 17 | 18 | @class QMUITableView; 19 | 20 | @protocol QMUICellHeightCache_UITableViewDataSource 21 | 22 | @optional 23 | /// 搭配 QMUICellHeightCache 使用,对于 UITableView 而言如果要用 QMUICellHeightCache 那套高度计算方式,则必须实现这个方法 24 | - (nullable __kindof UITableViewCell *)qmui_tableView:(nullable UITableView *)tableView cellWithIdentifier:(nonnull NSString *)identifier; 25 | 26 | @end 27 | 28 | @protocol QMUICellHeightKeyCache_UITableViewDelegate 29 | 30 | @optional 31 | 32 | - (nonnull id)qmui_tableView:(nonnull UITableView *)tableView cacheKeyForRowAtIndexPath:(nonnull NSIndexPath *)indexPath; 33 | @end 34 | 35 | @protocol QMUITableViewDelegate 36 | 37 | @optional 38 | 39 | /** 40 | * 自定义要在- (BOOL)touchesShouldCancelInContentView:(UIView *)view内的逻辑
41 | * 若delegate不实现这个方法,则默认对所有UIControl返回NO(UIButton除外,它会返回YES),非UIControl返回YES。 42 | */ 43 | - (BOOL)tableView:(nonnull QMUITableView *)tableView touchesShouldCancelInContentView:(nonnull UIView *)view; 44 | 45 | @end 46 | 47 | 48 | @protocol QMUITableViewDataSource 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUITestView.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUITestView.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 16/1/28. 14 | // 15 | 16 | #import 17 | 18 | @interface QMUITestView : UIView 19 | 20 | @end 21 | 22 | 23 | @interface QMUITestWindow : UIWindow 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUITheme/QMUITheme.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // QMUITheme.h 10 | // QMUIKit 11 | // 12 | // Created by MoLice on 2019/J/20. 13 | // 14 | 15 | #ifndef QMUITheme_h 16 | #define QMUITheme_h 17 | 18 | #import "QMUIThemeManagerCenter.h" 19 | #import "QMUIThemeManager.h" 20 | #import "UIColor+QMUITheme.h" 21 | #import "UIImage+QMUITheme.h" 22 | #import "UIVisualEffect+QMUITheme.h" 23 | #import "UIView+QMUITheme.h" 24 | #import "UIViewController+QMUITheme.h" 25 | 26 | #endif /* QMUITheme_h */ 27 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUITheme/QMUIThemeManagerCenter.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // QMUIThemeManagerCenter.h 10 | // QMUIKit 11 | // 12 | // Created by MoLice on 2019/S/4. 13 | // 14 | 15 | #import 16 | #import "QMUIThemeManager.h" 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | extern NSString *const QMUIThemeManagerNameDefault; 21 | 22 | /** 23 | 用于获取 QMUIThemeManager,具体使用请查看 QMUIThemeManager 的注释。 24 | */ 25 | @interface QMUIThemeManagerCenter : NSObject 26 | 27 | @property(class, nonatomic, strong, readonly) QMUIThemeManager *defaultThemeManager; 28 | @property(class, nonatomic, copy, readonly) NSArray *themeManagers; 29 | + (nullable QMUIThemeManager *)themeManagerWithName:(__kindof NSObject *)name; 30 | @end 31 | 32 | NS_ASSUME_NONNULL_END 33 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUITheme/UIView+QMUITheme.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // UIView+QMUITheme.h 10 | // QMUIKit 11 | // 12 | // Created by MoLice on 2019/6/21. 13 | // 14 | 15 | #import 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | @class QMUIThemeManager; 20 | 21 | @interface UIView (QMUITheme) 22 | 23 | /** 24 | 注册当前 view 里需要在主题变化时被重新设置的 property,当主题变化时,会通过 qmui_themeDidChangeByManager:identifier:theme: 来重新调用一次 self.xxx = xxx,以达到刷新界面的目的。 25 | @param getters 属性的 getter, 内部会根据命名规则自动转换得到 setter,再通过 performSelector 的形式调用 getter 和 setter 26 | */ 27 | - (void)qmui_registerThemeColorProperties:(NSArray *)getters; 28 | 29 | /** 30 | 注销通过 qmui_registerThemeColorProperties: 注册的 property 31 | @param getters 属性的 getter, 内部会根据命名规则自动转换得到 setter,再通过 performSelector 的形式调用 getter 和 setter 32 | */ 33 | - (void)qmui_unregisterThemeColorProperties:(NSArray *)getters; 34 | 35 | /** 36 | 当主题变化时这个方法会被调用,通过 registerThemeColorProperties: 方法注册的属性也会在这里被更新(所以记得要调用 super)。registerThemeColorProperties: 无法满足的需求可以重写这个方法自行实现。 37 | @param manager 当前的主题管理对象 38 | @param identifier 当前主题的标志,可自行修改参数类型为目标类型 39 | @param theme 当前主题对象,可自行修改参数类型为目标类型 40 | */ 41 | - (void)qmui_themeDidChangeByManager:(nullable QMUIThemeManager *)manager identifier:(nullable __kindof NSObject *)identifier theme:(nullable __kindof NSObject *)theme NS_REQUIRES_SUPER; 42 | 43 | @property(nonatomic, copy, nullable) void (^qmui_themeDidChangeBlock)(void); 44 | 45 | @end 46 | 47 | NS_ASSUME_NONNULL_END 48 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUITheme/UIViewController+QMUITheme.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // UIViewController+QMUITheme.h 10 | // QMUIKit 11 | // 12 | // Created by MoLice on 2019/6/26. 13 | // 14 | 15 | #import 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | @class QMUIThemeManager; 20 | 21 | @interface UIViewController (QMUITheme) 22 | 23 | /** 24 | 当主题变化时这个方法会被调用,不管当前 vc 是否处于可视状态。 25 | @param manager 当前的主题管理对象 26 | @param identifier 当前主题的标志,可自行修改参数类型为目标类型 27 | @param theme 当前主题对象,可自行修改参数类型为目标类型 28 | @warning 这个方法会在任何可能的时机被调用,不应该认为它一定比 viewDidLoad、viewWillAppear:、viewDidAppear: 晚。 29 | */ 30 | - (void)qmui_themeDidChangeByManager:(QMUIThemeManager *)manager identifier:(__kindof NSObject *)identifier theme:(__kindof NSObject *)theme NS_REQUIRES_SUPER; 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIWeakObjectContainer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUIWeakObjectContainer.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/7/24. 14 | // 15 | 16 | #import 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | /** 21 | 一个常见的场景:当通过 objc_setAssociatedObject 以弱引用的方式(OBJC_ASSOCIATION_ASSIGN)绑定对象A时,假如对象A稍后被释放了,则通过 objc_getAssociatedObject 再次试图访问对象A时会导致野指针。 22 | 这时你可以将对象A包装为一个 QMUIWeakObjectContainer,并改为通过强引用方式(OBJC_ASSOCIATION_RETAIN_NONATOMIC/OBJC_ASSOCIATION_RETAIN)绑定这个 QMUIWeakObjectContainer,进而安全地获取原始对象A。 23 | */ 24 | @interface QMUIWeakObjectContainer : NSProxy 25 | 26 | /// 将一个 object 包装到一个 QMUIWeakObjectContainer 里 27 | - (instancetype)initWithObject:(id)object; 28 | - (instancetype)init; 29 | + (instancetype)containerWithObject:(id)object; 30 | 31 | /// 获取原始对象 object,如果 object 已被释放则该属性返回 nil 32 | @property (nullable, nonatomic, weak) id object; 33 | @property(nonatomic, assign, readonly) BOOL isQMUIWeakObjectContainer; 34 | 35 | @end 36 | 37 | NS_ASSUME_NONNULL_END 38 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/QMUIWindowSizeMonitor.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // QMUIWindowSizeMonitor.h 10 | // qmuidemo 11 | // 12 | // Created by ziezheng on 2019/5/27. 13 | // 14 | 15 | #import 16 | #import 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @protocol QMUIWindowSizeMonitorProtocol 21 | 22 | @optional 23 | 24 | /** 25 | 当继承自 UIResponder 的对象,比如 UIView 或 UIViewController 实现了这个方法时,其所属的 window 在大小发生改变后在这个方法回调。 26 | @note 类似系统的 [-viewWillTransitionToSize:withTransitionCoordinator:],但是系统这个方法回调时 window 的大小实际上还未发生改变,如果你需要在 window 大小发生之后且在 layout 之前来处理一些逻辑时,可以放到这个方法去实现。 27 | @note 如果子类和父类同时实现了该方法,则两个方法均会被调用,调用顺序是先父类后子类。 28 | @param size 所属窗口的新大小 29 | */ 30 | 31 | - (void)windowDidTransitionToSize:(CGSize)size; 32 | 33 | @end 34 | 35 | @interface UIResponder (QMUIWindowSizeMonitor) 36 | 37 | @end 38 | 39 | typedef void (^QMUIWindowSizeObserverHandler)(CGSize newWindowSize); 40 | 41 | @interface NSObject (QMUIWindowSizeMonitor) 42 | 43 | /** 44 | 为当前对象添加主窗口 (UIApplication Delegate Window)的大小变化的监听,同一对象可重复添加多个监听,当对象销毁时监听自动失效。 45 | 46 | @param handler 窗口大小发生改变时的回调 47 | */ 48 | - (void)qmui_addSizeObserverForMainWindow:(QMUIWindowSizeObserverHandler)handler; 49 | /** 50 | 为当前对象添加指定窗口的大小变化监听,同一对象可重复添加多个监听,当对象销毁时监听自动失效。 51 | 52 | @param window 要监听的窗口 53 | @param handler 窗口大小发生改变时的回调 54 | */ 55 | - (void)qmui_addSizeObserverForWindow:(UIWindow *)window handler:(QMUIWindowSizeObserverHandler)handler; 56 | 57 | @end 58 | 59 | NS_ASSUME_NONNULL_END 60 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/StaticTableView/UITableView+QMUIStaticCell.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UITableView+QMUIStaticCell.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 2017/6/20. 14 | // 15 | 16 | #import 17 | #import 18 | 19 | @class QMUIStaticTableViewCellDataSource; 20 | 21 | /** 22 | * 配合 QMUIStaticTableViewCellDataSource 使用,主要负责: 23 | * 1. 提供 property 去绑定一个 static dataSource 24 | * 2. 重写 setDataSource:、setDelegate: 方法,自动实现 UITableViewDataSource、UITableViewDelegate 里一些必要的方法 25 | * 26 | * 使用方式:初始化一个 QMUIStaticTableViewCellDataSource 并将其赋值给 qmui_staticCellDataSource 属性即可。 27 | * 28 | * @warning 当要动态更新 dataSource 时,可直接修改 self.qmui_staticCellDataSource.cellDataSections 数组,或者创建一个新的 QMUIStaticTableViewCellDataSource。不管用哪种方法,都不需要手动调用 reloadData,tableView 会自动刷新的。 29 | */ 30 | @interface UITableView (QMUI_StaticCell) 31 | 32 | @property(nonatomic, strong) QMUIStaticTableViewCellDataSource *qmui_staticCellDataSource; 33 | @end 34 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/ToastView/QMUIToastAnimator.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUIToastAnimator.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 2016/12/12. 14 | // 15 | 16 | #import 17 | 18 | @class QMUIToastView; 19 | 20 | /** 21 | * `QMUIToastAnimatorDelegate`是所有`QMUIToastAnimator`或者其子类必须遵循的协议,是整个动画过程实现的地方。 22 | */ 23 | @protocol QMUIToastAnimatorDelegate 24 | 25 | @required 26 | 27 | - (void)showWithCompletion:(void (^)(BOOL finished))completion; 28 | - (void)hideWithCompletion:(void (^)(BOOL finished))completion; 29 | - (BOOL)isShowing; 30 | - (BOOL)isAnimating; 31 | @end 32 | 33 | typedef NS_ENUM(NSInteger, QMUIToastAnimationType) { 34 | QMUIToastAnimationTypeFade = 0, 35 | QMUIToastAnimationTypeZoom, 36 | QMUIToastAnimationTypeSlide 37 | }; 38 | 39 | /** 40 | * `QMUIToastAnimator`可以让你通过实现一些协议来自定义ToastView显示和隐藏的动画。你可以继承`QMUIToastAnimator`,然后实现`QMUIToastAnimatorDelegate`中的方法,即可实现自定义的动画。QMUIToastAnimator默认也提供了几种type的动画:1、QMUIToastAnimationTypeFade;2、QMUIToastAnimationTypeZoom;3、QMUIToastAnimationTypeSlide; 41 | */ 42 | @interface QMUIToastAnimator : NSObject 43 | 44 | /** 45 | * 初始化方法,请务必使用这个方法来初始化。 46 | * 47 | * @param toastView 要使用这个animator的QMUIToastView实例。 48 | */ 49 | - (instancetype)initWithToastView:(QMUIToastView *)toastView NS_DESIGNATED_INITIALIZER; 50 | 51 | /** 52 | * 获取初始化传进来的QMUIToastView。 53 | */ 54 | @property(nonatomic, weak, readonly) QMUIToastView *toastView; 55 | 56 | /** 57 | * 指定QMUIToastAnimator做动画的类型type。此功能暂时未实现,目前所有动画类型都是QMUIToastAnimationTypeFade。 58 | */ 59 | @property(nonatomic, assign) QMUIToastAnimationType animationType; 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /QMUIKit/QMUIComponents/ToastView/QMUIToastBackgroundView.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUIToastBackgroundView.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 2016/12/11. 14 | // 15 | 16 | #import 17 | 18 | @interface QMUIToastBackgroundView : UIView 19 | 20 | /** 21 | * 是否需要磨砂,默认NO。仅支持iOS8及以上版本。可以通过修改`styleColor`来控制磨砂的效果。 22 | */ 23 | @property(nonatomic, assign) BOOL shouldBlurBackgroundView; 24 | 25 | @property(nullable, nonatomic, strong, readonly) UIVisualEffectView *effectView; 26 | 27 | /** 28 | * 如果不设置磨砂,则styleColor直接作为`QMUIToastBackgroundView`的backgroundColor;如果需要磨砂,则会新增加一个`UIVisualEffectView`放在`QMUIToastBackgroundView`上面。 29 | */ 30 | @property(nullable, nonatomic, strong) UIColor *styleColor UI_APPEARANCE_SELECTOR; 31 | 32 | /** 33 | * 设置圆角。 34 | */ 35 | @property(nonatomic, assign) CGFloat cornerRadius UI_APPEARANCE_SELECTOR; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /QMUIKit/QMUICore/QMUICore.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUICore.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 2017/5/17. 14 | // 15 | 16 | #import "QMUIHelper.h" 17 | #import "QMUICommonDefines.h" 18 | #import "QMUIRuntime.h" 19 | #import "QMUILab.h" 20 | #import "QMUIConfiguration.h" 21 | #import "QMUIConfigurationMacros.h" 22 | -------------------------------------------------------------------------------- /QMUIKit/QMUIMainFrame/QMUITabBarViewController.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUITabBarViewController.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 15/3/29. 14 | // 15 | 16 | #import 17 | 18 | /** 19 | * 建议作为项目里 tabBarController 的基类,内部处理了几件事情: 20 | * 1. 配合配置表修改 tabBar 的样式。 21 | * 2. 管理界面支持显示的方向。 22 | * 23 | * @warning 当你需要实现“tabBarController 首页那几个界面显示 tabBar,而 push 进去的所有子界面都隐藏 tabBar”的效果时,可将配置表里的 HidesBottomBarWhenPushedInitially 改为 YES,然后手动将 tabBarController 首页的那几个界面的 hidesBottomBarWhenPushed 属性改为 NO,即可实现。 24 | * 25 | * Inherent your tabBarController from this, so you can enjoy: 26 | * 1. a tabBar with styles defined in configuration templates 27 | * 2. a tabBar that manages supported interface orientations 28 | * 29 | */ 30 | @interface QMUITabBarViewController : UITabBarController 31 | 32 | /** 33 | * 初始化时调用的方法,会在 initWithNibName:bundle: 和 initWithCoder: 这两个指定的初始化方法中被调用,所以子类如果需要同时支持两个初始化方法,则建议把初始化时要做的事情放到这个方法里。否则仅需重写要支持的那个初始化方法即可。 34 | * Initialization method. Will be called in `initWithNibName:bundle:` and `initWithCoder:`. Implement this method to be called in both initializers. 35 | */ 36 | - (void)didInitialize NS_REQUIRES_SUPER; 37 | @end 38 | -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_checkbox16.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "QMUI_checkbox16.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_checkbox16.imageset/QMUI_checkbox16.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 16.000000 8.000000 m 14 | 16.000000 3.581722 12.418278 0.000000 8.000000 0.000000 c 15 | 3.581722 0.000000 0.000000 3.581722 0.000000 8.000000 c 16 | 0.000000 12.418278 3.581722 16.000000 8.000000 16.000000 c 17 | 12.418278 16.000000 16.000000 12.418278 16.000000 8.000000 c 18 | h 19 | W* 20 | n 21 | q 22 | 1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm 23 | 0.000000 0.000000 0.000000 scn 24 | 15.000000 8.000000 m 25 | 15.000000 4.134007 11.865993 1.000000 8.000000 1.000000 c 26 | 8.000000 -1.000000 l 27 | 12.970563 -1.000000 17.000000 3.029437 17.000000 8.000000 c 28 | 15.000000 8.000000 l 29 | h 30 | 8.000000 1.000000 m 31 | 4.134007 1.000000 1.000000 4.134007 1.000000 8.000000 c 32 | -1.000000 8.000000 l 33 | -1.000000 3.029437 3.029437 -1.000000 8.000000 -1.000000 c 34 | 8.000000 1.000000 l 35 | h 36 | 1.000000 8.000000 m 37 | 1.000000 11.865993 4.134007 15.000000 8.000000 15.000000 c 38 | 8.000000 17.000000 l 39 | 3.029437 17.000000 -1.000000 12.970563 -1.000000 8.000000 c 40 | 1.000000 8.000000 l 41 | h 42 | 8.000000 15.000000 m 43 | 11.865993 15.000000 15.000000 11.865993 15.000000 8.000000 c 44 | 17.000000 8.000000 l 45 | 17.000000 12.970563 12.970563 17.000000 8.000000 17.000000 c 46 | 8.000000 15.000000 l 47 | h 48 | f 49 | n 50 | Q 51 | Q 52 | 53 | endstream 54 | endobj 55 | 56 | 3 0 obj 57 | 1121 58 | endobj 59 | 60 | 4 0 obj 61 | << /Annots [] 62 | /Type /Page 63 | /MediaBox [ 0.000000 0.000000 16.000000 16.000000 ] 64 | /Resources 1 0 R 65 | /Contents 2 0 R 66 | /Parent 5 0 R 67 | >> 68 | endobj 69 | 70 | 5 0 obj 71 | << /Kids [ 4 0 R ] 72 | /Count 1 73 | /Type /Pages 74 | >> 75 | endobj 76 | 77 | 6 0 obj 78 | << /Type /Catalog 79 | /Pages 5 0 R 80 | >> 81 | endobj 82 | 83 | xref 84 | 0 7 85 | 0000000000 65535 f 86 | 0000000010 00000 n 87 | 0000000034 00000 n 88 | 0000001211 00000 n 89 | 0000001234 00000 n 90 | 0000001407 00000 n 91 | 0000001481 00000 n 92 | trailer 93 | << /ID [ (some) (id) ] 94 | /Root 6 0 R 95 | /Size 7 96 | >> 97 | startxref 98 | 1540 99 | %%EOF -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_checkbox16_checked.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "QMUI_checkbox16_checked.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_checkbox16_checked.imageset/QMUI_checkbox16_checked.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm 14 | 0.000000 0.000000 0.000000 scn 15 | 8.000000 0.000000 m 16 | 12.418278 0.000000 16.000000 3.581722 16.000000 8.000000 c 17 | 16.000000 12.418278 12.418278 16.000000 8.000000 16.000000 c 18 | 3.581722 16.000000 0.000000 12.418278 0.000000 8.000000 c 19 | 0.000000 3.581722 3.581722 0.000000 8.000000 0.000000 c 20 | h 21 | 11.776730 10.175852 m 22 | 11.980856 10.454206 11.920683 10.845332 11.642329 11.049458 c 23 | 11.363976 11.253584 10.972849 11.193410 10.768724 10.915056 c 24 | 7.199536 6.047983 l 25 | 5.532851 7.714668 l 26 | 5.288773 7.958746 4.893045 7.958747 4.648967 7.714669 c 27 | 4.404890 7.470592 4.404890 7.074863 4.648967 6.830786 c 28 | 6.830785 4.648968 l 29 | 6.959730 4.520022 7.138559 4.453823 7.320384 4.467729 c 30 | 7.502208 4.481633 7.668892 4.574255 7.776731 4.721307 c 31 | 11.776730 10.175852 l 32 | h 33 | f* 34 | n 35 | Q 36 | 37 | endstream 38 | endobj 39 | 40 | 3 0 obj 41 | 836 42 | endobj 43 | 44 | 4 0 obj 45 | << /Annots [] 46 | /Type /Page 47 | /MediaBox [ 0.000000 0.000000 16.000000 16.000000 ] 48 | /Resources 1 0 R 49 | /Contents 2 0 R 50 | /Parent 5 0 R 51 | >> 52 | endobj 53 | 54 | 5 0 obj 55 | << /Kids [ 4 0 R ] 56 | /Count 1 57 | /Type /Pages 58 | >> 59 | endobj 60 | 61 | 6 0 obj 62 | << /Type /Catalog 63 | /Pages 5 0 R 64 | >> 65 | endobj 66 | 67 | xref 68 | 0 7 69 | 0000000000 65535 f 70 | 0000000010 00000 n 71 | 0000000034 00000 n 72 | 0000000926 00000 n 73 | 0000000948 00000 n 74 | 0000001121 00000 n 75 | 0000001195 00000 n 76 | trailer 77 | << /ID [ (some) (id) ] 78 | /Root 6 0 R 79 | /Size 7 80 | >> 81 | startxref 82 | 1254 83 | %%EOF -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_checkbox16_disabled.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "QMUI_checkbox16_disabled.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_checkbox16_indeterminate.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "QMUI_checkbox16_indeterminate.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_console_clear.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "QMUI_console_clear.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_console_clear.imageset/QMUI_console_clear.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tencent/QMUI_iOS/4dca2347dcb5feecdbb39fc99b36004c8c94a958/QMUIKit/QMUIResources/Images.xcassets/QMUI_console_clear.imageset/QMUI_console_clear.pdf -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_console_filter.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "QMUI_console_filter.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_console_filter.imageset/QMUI_console_filter.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tencent/QMUI_iOS/4dca2347dcb5feecdbb39fc99b36004c8c94a958/QMUIKit/QMUIResources/Images.xcassets/QMUI_console_filter.imageset/QMUI_console_filter.pdf -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_console_filter_selected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "QMUI_console_filter_selected.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_console_filter_selected.imageset/QMUI_console_filter_selected.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tencent/QMUI_iOS/4dca2347dcb5feecdbb39fc99b36004c8c94a958/QMUIKit/QMUIResources/Images.xcassets/QMUI_console_filter_selected.imageset/QMUI_console_filter_selected.pdf -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_console_logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "QMUI_console_logo.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_console_logo.imageset/QMUI_console_logo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tencent/QMUI_iOS/4dca2347dcb5feecdbb39fc99b36004c8c94a958/QMUIKit/QMUIResources/Images.xcassets/QMUI_console_logo.imageset/QMUI_console_logo.pdf -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_emotion_delete.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "QMUI_emotion_delete.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_emotion_delete.imageset/QMUI_emotion_delete.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tencent/QMUI_iOS/4dca2347dcb5feecdbb39fc99b36004c8c94a958/QMUIKit/QMUIResources/Images.xcassets/QMUI_emotion_delete.imageset/QMUI_emotion_delete.pdf -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_hiddenAlbum.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "QMUI_hiddenAlbum.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_hiddenAlbum.imageset/QMUI_hiddenAlbum.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tencent/QMUI_iOS/4dca2347dcb5feecdbb39fc99b36004c8c94a958/QMUIKit/QMUIResources/Images.xcassets/QMUI_hiddenAlbum.imageset/QMUI_hiddenAlbum.pdf -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_icloud_download_fault.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "QMUI_icloud_download_fault.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_icloud_download_fault.imageset/QMUI_icloud_download_fault.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tencent/QMUI_iOS/4dca2347dcb5feecdbb39fc99b36004c8c94a958/QMUIKit/QMUIResources/Images.xcassets/QMUI_icloud_download_fault.imageset/QMUI_icloud_download_fault.pdf -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_pickerImage_checkbox.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "QMUI_pickerImage_checkbox.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_pickerImage_checkbox.imageset/QMUI_pickerImage_checkbox.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tencent/QMUI_iOS/4dca2347dcb5feecdbb39fc99b36004c8c94a958/QMUIKit/QMUIResources/Images.xcassets/QMUI_pickerImage_checkbox.imageset/QMUI_pickerImage_checkbox.pdf -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_pickerImage_checkbox_checked.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "QMUI_pickerImage_checkbox_checked.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_pickerImage_checkbox_checked.imageset/QMUI_pickerImage_checkbox_checked.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tencent/QMUI_iOS/4dca2347dcb5feecdbb39fc99b36004c8c94a958/QMUIKit/QMUIResources/Images.xcassets/QMUI_pickerImage_checkbox_checked.imageset/QMUI_pickerImage_checkbox_checked.pdf -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_pickerImage_favorite.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "QMUI_pickerImage_favorite.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_pickerImage_favorite.imageset/QMUI_pickerImage_favorite.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tencent/QMUI_iOS/4dca2347dcb5feecdbb39fc99b36004c8c94a958/QMUIKit/QMUIResources/Images.xcassets/QMUI_pickerImage_favorite.imageset/QMUI_pickerImage_favorite.pdf -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_pickerImage_video_mark.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "QMUI_pickerImage_video_mark.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_pickerImage_video_mark.imageset/QMUI_pickerImage_video_mark.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tencent/QMUI_iOS/4dca2347dcb5feecdbb39fc99b36004c8c94a958/QMUIKit/QMUIResources/Images.xcassets/QMUI_pickerImage_video_mark.imageset/QMUI_pickerImage_video_mark.pdf -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_previewImage_checkbox.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "QMUI_previewImage_checkbox.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_previewImage_checkbox.imageset/QMUI_previewImage_checkbox.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tencent/QMUI_iOS/4dca2347dcb5feecdbb39fc99b36004c8c94a958/QMUIKit/QMUIResources/Images.xcassets/QMUI_previewImage_checkbox.imageset/QMUI_previewImage_checkbox.pdf -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_previewImage_checkbox_checked.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "QMUI_previewImage_checkbox_checked.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_previewImage_checkbox_checked.imageset/QMUI_previewImage_checkbox_checked.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tencent/QMUI_iOS/4dca2347dcb5feecdbb39fc99b36004c8c94a958/QMUIKit/QMUIResources/Images.xcassets/QMUI_previewImage_checkbox_checked.imageset/QMUI_previewImage_checkbox_checked.pdf -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_tips_done.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "QMUI_tips_done.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_tips_done.imageset/QMUI_tips_done.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tencent/QMUI_iOS/4dca2347dcb5feecdbb39fc99b36004c8c94a958/QMUIKit/QMUIResources/Images.xcassets/QMUI_tips_done.imageset/QMUI_tips_done.pdf -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_tips_error.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "QMUI_tips_error.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_tips_error.imageset/QMUI_tips_error.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tencent/QMUI_iOS/4dca2347dcb5feecdbb39fc99b36004c8c94a958/QMUIKit/QMUIResources/Images.xcassets/QMUI_tips_error.imageset/QMUI_tips_error.pdf -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_tips_info.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "QMUI_tips_info.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /QMUIKit/QMUIResources/Images.xcassets/QMUI_tips_info.imageset/QMUI_tips_info.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tencent/QMUI_iOS/4dca2347dcb5feecdbb39fc99b36004c8c94a958/QMUIKit/QMUIResources/Images.xcassets/QMUI_tips_info.imageset/QMUI_tips_info.pdf -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/NSArray+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // NSArray+QMUI.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2017/11/14. 14 | // 15 | 16 | #import 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @interface NSArray (QMUI) 21 | 22 | /** 23 | 将多个对象合并成一个数组,如果参数类型是数组则会将数组内的元素拆解出来加到 return 内(只会拆解一层,所以多维数组不处理) 24 | 25 | @param object 要合并的多个数组 26 | @return 合并完的结果 27 | */ 28 | + (instancetype)qmui_arrayWithObjects:(ObjectType)object, ...; 29 | 30 | /** 31 | * 将多维数组打平成一维数组再遍历所有子元素 32 | */ 33 | - (void)qmui_enumerateNestedArrayWithBlock:(void (NS_NOESCAPE^)(id obj, BOOL *stop))block; 34 | 35 | /** 36 | * 将多维数组递归转换成 mutable 多维数组 37 | */ 38 | - (NSMutableArray *)qmui_mutableCopyNestedArray; 39 | 40 | /** 41 | * 过滤数组元素,将 block 返回 YES 的 item 重新组装成一个数组返回 42 | */ 43 | - (NSArray *)qmui_filterWithBlock:(BOOL (NS_NOESCAPE^)(ObjectType item))block; 44 | 45 | /** 46 | 过滤数组元素,将第一个令 block 返回值为 YES 的元素返回,如果不存在则返回 nil 47 | */ 48 | - (ObjectType _Nullable)qmui_firstMatchWithBlock:(BOOL (NS_NOESCAPE^)(ObjectType item))block; 49 | 50 | /** 51 | * 转换数组元素,将每个 item 都经过 block 转换成一遍后返回一个等长的数组。 52 | */ 53 | - (NSArray *)qmui_mapWithBlock:(id (NS_NOESCAPE^)(ObjectType item, NSInteger index))block; 54 | 55 | /** 56 | * 转换数组元素,将每个 item 经过 block 转换为另一个元素,如果希望移除该 item,可返回 nil。当所有元素都被移除时,本方法返回空的容器。 57 | */ 58 | - (NSArray *)qmui_compactMapWithBlock:(id _Nullable (NS_NOESCAPE^)(ObjectType item))block; 59 | 60 | @end 61 | 62 | NS_ASSUME_NONNULL_END 63 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/NSCharacterSet+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // NSCharacterSet+QMUI.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/9/17. 14 | // 15 | 16 | #import 17 | 18 | @interface NSCharacterSet (QMUI) 19 | 20 | /** 21 | 也即在系统的 URLQueryAllowedCharacterSet 基础上去掉“#&=”这3个字符,专用于 URL query 里来源于用户输入的 value,避免服务器解析出现异常。 22 | */ 23 | @property (class, readonly, copy) NSCharacterSet *qmui_URLUserInputQueryAllowedCharacterSet; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/NSCharacterSet+QMUI.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // NSCharacterSet+QMUI.m 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/9/17. 14 | // 15 | 16 | #import "NSCharacterSet+QMUI.h" 17 | 18 | @implementation NSCharacterSet (QMUI) 19 | 20 | + (NSCharacterSet *)qmui_URLUserInputQueryAllowedCharacterSet { 21 | NSMutableCharacterSet *set = [NSCharacterSet URLQueryAllowedCharacterSet].mutableCopy; 22 | [set removeCharactersInString:@"#&="]; 23 | return set.copy; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/NSDictionary+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // NSDictionary+QMUI.h 11 | // QMUIKit 12 | // 13 | // Created by molice on 2023/7/21. 14 | // Copyright © 2023 QMUI Team. All rights reserved. 15 | // 16 | 17 | #import 18 | 19 | NS_ASSUME_NONNULL_BEGIN 20 | 21 | @interface NSDictionary (QMUI) 22 | 23 | /** 24 | * 转换字典的元素,将每个 key-value 经过 block 转换为另一个 key-value,如果希望移除该 item,可返回 nil。当所有元素都被移除时,本方法返回空的容器。 25 | 对应 -[NSArray(QMUI) qmui_compactMapWithBlock],是觉得没必要区分 compact 和非 compact 了。 26 | */ 27 | - (NSDictionary * _Nullable)qmui_mapWithBlock:(NSDictionary * _Nullable (NS_NOESCAPE^)(KeyType key, ObjectType value))block; 28 | 29 | /** 30 | 深度转换字典的元素,同 qmui_mapWithBlock:,但区别在于如果 object 是一个 NSDictionary,则它会递归再 map,最终把所有的 key-value 都转换一遍。 31 | 32 | @warning 面对嵌套 dictionary 时,本方法的 block 里的参数 value 有可能会传 NSDictionary 类型,但实际上你对其转换后的返回值只有 key 会被使用,value 会被丢弃。 33 | */ 34 | - (NSDictionary * _Nullable)qmui_deepMapWithBlock:(NSDictionary * _Nullable (NS_NOESCAPE^)(KeyType key, ObjectType value))block; 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/NSMethodSignature+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // NSMethodSignature+QMUI.h 10 | // QMUIKit 11 | // 12 | // Created by MoLice on 2019/A/28. 13 | // 14 | 15 | #import 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | @interface NSMethodSignature (QMUI) 20 | 21 | /** 22 | 返回一个避免 crash 的方法签名,用于重写 methodSignatureForSelector: 时作为垫底的 return 方案 23 | */ 24 | @property(nullable, class, nonatomic, readonly) NSMethodSignature *qmui_avoidExceptionSignature; 25 | 26 | /** 27 | 以 NSString 格式返回当前 NSMethodSignature 的 typeEncoding,例如 v@: 28 | */ 29 | @property(nullable, nonatomic, copy, readonly) NSString *qmui_typeString; 30 | 31 | /** 32 | 以 const char 格式返回当前 NSMethodSignature 的 typeEncoding,例如 v@: 33 | */ 34 | @property(nullable, nonatomic, readonly) const char *qmui_typeEncoding; 35 | @end 36 | 37 | NS_ASSUME_NONNULL_END 38 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/NSMethodSignature+QMUI.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // NSMethodSignature+QMUI.m 10 | // QMUIKit 11 | // 12 | // Created by MoLice on 2019/A/28. 13 | // 14 | 15 | #import "NSMethodSignature+QMUI.h" 16 | #import "NSObject+QMUI.h" 17 | #import "QMUICore.h" 18 | 19 | @implementation NSMethodSignature (QMUI) 20 | 21 | + (NSMethodSignature *)qmui_avoidExceptionSignature { 22 | // https://github.com/facebookarchive/AsyncDisplayKit/pull/1562 23 | // Unfortunately, in order to get this object to work properly, the use of a method which creates an NSMethodSignature 24 | // from a C string. -methodSignatureForSelector is called when a compiled definition for the selector cannot be found. 25 | // This is the place where we have to create our own dud NSMethodSignature. This is necessary because if this method 26 | // returns nil, a selector not found exception is raised. The string argument to -signatureWithObjCTypes: outlines 27 | // the return type and arguments to the message. To return a dud NSMethodSignature, pretty much any signature will 28 | // suffice. Since the -forwardInvocation call will do nothing if the delegate does not respond to the selector, 29 | // the dud NSMethodSignature simply gets us around the exception. 30 | return [NSMethodSignature signatureWithObjCTypes:"@^v^c"]; 31 | } 32 | 33 | - (NSString *)qmui_typeString { 34 | BeginIgnorePerformSelectorLeaksWarning 35 | NSString *typeString = [self performSelector:NSSelectorFromString([NSString stringWithFormat:@"_%@String", @"type"])]; 36 | EndIgnorePerformSelectorLeaksWarning 37 | return typeString; 38 | } 39 | 40 | - (const char *)qmui_typeEncoding { 41 | return self.qmui_typeString.UTF8String; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/NSNumber+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // NSNumber+QMUI.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/1/16. 14 | // 15 | 16 | #import 17 | #import 18 | 19 | @interface NSNumber (QMUI) 20 | 21 | @property(nonatomic, assign, readonly) CGFloat qmui_CGFloatValue; 22 | @end 23 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/NSNumber+QMUI.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // NSNumber+QMUI.m 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/1/16. 14 | // 15 | 16 | #import "NSNumber+QMUI.h" 17 | 18 | @implementation NSNumber (QMUI) 19 | 20 | - (CGFloat)qmui_CGFloatValue { 21 | #if CGFLOAT_IS_DOUBLE 22 | return self.doubleValue; 23 | #else 24 | return self.floatValue; 25 | #endif 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/NSParagraphStyle+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // NSParagraphStyle+QMUI.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 16/8/9. 14 | // 15 | 16 | #import 17 | #import 18 | 19 | @interface NSParagraphStyle (QMUI) 20 | 21 | /** 22 | * 快速创建一个NSMutableParagraphStyle,等同于`qmui_paragraphStyleWithLineHeight:lineBreakMode:NSLineBreakByWordWrapping textAlignment:NSTextAlignmentLeft`。 23 | * 注意 NSParagraphStyle.lineBreakMode 默认值为 NSLineBreakByWordWrapping,而 UILabel.lineBreakMode 默认值为 NSLineBreakByTruncatingTail。如果 UILabel.attributedText 里显式设置了 NSParagraphStyle,则 UILabel.lineBreakMode 返回的值会由 attributedText 里的 NSParagraphStyle.lineBreakMode 决定。 24 | * @param lineHeight 行高 25 | * @return 一个NSMutableParagraphStyle对象 26 | */ 27 | + (instancetype)qmui_paragraphStyleWithLineHeight:(CGFloat)lineHeight; 28 | 29 | /** 30 | * 快速创建一个NSMutableParagraphStyle,等同于`qmui_paragraphStyleWithLineHeight:lineBreakMode:textAlignment:NSTextAlignmentLeft` 31 | * @param lineHeight 行高 32 | * @param lineBreakMode 换行模式 33 | * @return 一个NSMutableParagraphStyle对象 34 | */ 35 | + (instancetype)qmui_paragraphStyleWithLineHeight:(CGFloat)lineHeight lineBreakMode:(NSLineBreakMode)lineBreakMode; 36 | 37 | /** 38 | * 快速创建一个NSMutableParagraphStyle 39 | * @param lineHeight 行高 40 | * @param lineBreakMode 换行模式 41 | * @param textAlignment 文本对齐方式 42 | * @return 一个NSMutableParagraphStyle对象 43 | */ 44 | + (instancetype)qmui_paragraphStyleWithLineHeight:(CGFloat)lineHeight lineBreakMode:(NSLineBreakMode)lineBreakMode textAlignment:(NSTextAlignment)textAlignment; 45 | @end 46 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/NSParagraphStyle+QMUI.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // NSParagraphStyle+QMUI.m 11 | // qmui 12 | // 13 | // Created by QMUI Team on 16/8/9. 14 | // 15 | 16 | #import "NSParagraphStyle+QMUI.h" 17 | 18 | @implementation NSParagraphStyle (QMUI) 19 | 20 | + (instancetype)qmui_paragraphStyleWithLineHeight:(CGFloat)lineHeight { 21 | return [self qmui_paragraphStyleWithLineHeight:lineHeight lineBreakMode:NSLineBreakByWordWrapping textAlignment:NSTextAlignmentLeft]; 22 | } 23 | 24 | + (instancetype)qmui_paragraphStyleWithLineHeight:(CGFloat)lineHeight lineBreakMode:(NSLineBreakMode)lineBreakMode { 25 | return [self qmui_paragraphStyleWithLineHeight:lineHeight lineBreakMode:lineBreakMode textAlignment:NSTextAlignmentLeft]; 26 | } 27 | 28 | + (instancetype)qmui_paragraphStyleWithLineHeight:(CGFloat)lineHeight lineBreakMode:(NSLineBreakMode)lineBreakMode textAlignment:(NSTextAlignment)textAlignment { 29 | Class className = ![self isMemberOfClass:NSMutableParagraphStyle.class] ? NSMutableParagraphStyle.class : self;// 保证如果有 NSMutableParagraphStyle 的子类来调用这个方法,也可以用子类的 Class 去初始化 30 | NSMutableParagraphStyle *paragraphStyle = [[className alloc] init]; 31 | paragraphStyle.minimumLineHeight = lineHeight; 32 | paragraphStyle.maximumLineHeight = lineHeight; 33 | paragraphStyle.lineBreakMode = lineBreakMode; 34 | paragraphStyle.alignment = textAlignment; 35 | return paragraphStyle; 36 | } 37 | @end 38 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/NSPointerArray+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // NSPointerArray+QMUI.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/4/12. 14 | // 15 | 16 | #import 17 | 18 | @interface NSPointerArray (QMUI) 19 | 20 | - (NSUInteger)qmui_indexOfPointer:(nullable void *)pointer; 21 | - (BOOL)qmui_containsPointer:(nullable void *)pointer; 22 | @end 23 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/NSPointerArray+QMUI.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // NSPointerArray+QMUI.m 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/4/12. 14 | // 15 | 16 | #import "NSPointerArray+QMUI.h" 17 | #import "QMUICore.h" 18 | 19 | @implementation NSPointerArray (QMUI) 20 | 21 | + (void)load { 22 | static dispatch_once_t onceToken; 23 | dispatch_once(&onceToken, ^{ 24 | ExtendImplementationOfNonVoidMethodWithoutArguments([NSPointerArray class], @selector(description), NSString *, ^NSString *(NSPointerArray *selfObject, NSString *originReturnValue) { 25 | NSMutableString *result = [[NSMutableString alloc] initWithString:originReturnValue]; 26 | NSPointerArray *array = [selfObject copy]; 27 | for (NSInteger i = 0; i < array.count; i++) { 28 | ([result appendFormat:@"\npointer[%@] is %@", @(i), [array pointerAtIndex:i]]); 29 | } 30 | return result; 31 | }); 32 | }); 33 | } 34 | 35 | 36 | - (NSUInteger)qmui_indexOfPointer:(nullable void *)pointer { 37 | if (!pointer) { 38 | return NSNotFound; 39 | } 40 | 41 | NSPointerArray *array = [self copy]; 42 | for (NSUInteger i = 0; i < array.count; i++) { 43 | if ([array pointerAtIndex:i] == ((void *)pointer)) { 44 | return i; 45 | } 46 | } 47 | return NSNotFound; 48 | } 49 | 50 | - (BOOL)qmui_containsPointer:(void *)pointer { 51 | if (!pointer) { 52 | return NO; 53 | } 54 | if ([self qmui_indexOfPointer:pointer] != NSNotFound) { 55 | return YES; 56 | } 57 | return NO; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/NSRegularExpression+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // NSRegularExpression+QMUI.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2024/2/21. 14 | // 15 | 16 | #import 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @interface NSRegularExpression (QMUI) 21 | 22 | /// 某些场景频繁构造 NSRegularExpression 耗时较大,所以这里提供一个缓存的方式,如果你的场景非频繁,可以不用。 23 | + (nullable NSRegularExpression *)qmui_cachedRegularExpressionWithPattern:(NSString *)pattern options:(NSRegularExpressionOptions)options; 24 | 25 | /// 某些场景频繁构造 NSRegularExpression 耗时较大,所以这里提供一个缓存的方式,如果你的场景非频繁,可以不用。等价于 options 为 NSRegularExpressionCaseInsensitive。 26 | + (nullable NSRegularExpression *)qmui_cachedRegularExpressionWithPattern:(NSString *)pattern; 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/NSRegularExpression+QMUI.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // NSRegularExpression+QMUI.m 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2024/2/21. 14 | // 15 | 16 | #import "NSRegularExpression+QMUI.h" 17 | 18 | @implementation NSRegularExpression (QMUI) 19 | 20 | + (NSRegularExpression *)qmui_cachedRegularExpressionWithPattern:(NSString *)pattern options:(NSRegularExpressionOptions)options { 21 | if (!pattern.length) return nil; 22 | 23 | static NSCache *cache = nil; 24 | if (!cache) { 25 | cache = [[NSCache alloc] init]; 26 | cache.name = @"NSRegularExpression (QMUI)"; 27 | cache.countLimit = 100; 28 | } 29 | 30 | NSString *key = [NSString stringWithFormat:@"%@_%@", pattern, @(options)]; 31 | NSRegularExpression *reg = [cache objectForKey:key]; 32 | if (!reg) { 33 | reg = [NSRegularExpression regularExpressionWithPattern:pattern options:options error:nil]; 34 | if (!reg) return nil; 35 | [cache setObject:reg forKey:key]; 36 | } 37 | return reg; 38 | } 39 | 40 | + (NSRegularExpression *)qmui_cachedRegularExpressionWithPattern:(NSString *)pattern { 41 | return [self qmui_cachedRegularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive]; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/NSShadow+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // NSShadow+QMUI.h 10 | // QMUIKit 11 | // 12 | // Created by molice on 2022/9/6. 13 | // 14 | 15 | #import 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | @interface NSShadow (QMUI) 20 | 21 | + (instancetype)qmui_shadowWithColor:(nullable UIColor *)shadowColor 22 | shadowOffset:(CGSize)shadowOffset 23 | shadowRadius:(CGFloat)shadowRadius; 24 | @end 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/NSShadow+QMUI.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // NSShadow+QMUI.m 10 | // QMUIKit 11 | // 12 | // Created by molice on 2022/9/6. 13 | // 14 | 15 | #import "NSShadow+QMUI.h" 16 | 17 | @implementation NSShadow (QMUI) 18 | 19 | + (instancetype)qmui_shadowWithColor:(UIColor *)shadowColor shadowOffset:(CGSize)shadowOffset shadowRadius:(CGFloat)shadowRadius { 20 | NSShadow *shadow = NSShadow.new; 21 | shadow.shadowColor = shadowColor; 22 | shadow.shadowOffset = shadowOffset; 23 | shadow.shadowBlurRadius = shadowRadius; 24 | return shadow; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/NSURL+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // NSURL+QMUI.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/11/11. 14 | // 15 | 16 | #import 17 | 18 | @interface NSURL (QMUI) 19 | 20 | /** 21 | * 获取当前 query 的参数列表。 22 | * 23 | * @return query 参数列表,以字典返回。如果 absoluteString 为 nil 则返回 nil 24 | */ 25 | @property(nonatomic, copy, readonly) NSDictionary *qmui_queryItems; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/NSURL+QMUI.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // NSURL+QMUI.m 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/11/11. 14 | // 15 | 16 | #import "NSURL+QMUI.h" 17 | 18 | @implementation NSURL (QMUI) 19 | 20 | - (NSDictionary *)qmui_queryItems { 21 | if (!self.absoluteString.length) { 22 | return nil; 23 | } 24 | 25 | NSMutableDictionary *params = [[NSMutableDictionary alloc] init]; 26 | NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithString:self.absoluteString]; 27 | 28 | [urlComponents.queryItems enumerateObjectsUsingBlock:^(NSURLQueryItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 29 | if (obj.name) { 30 | [params setObject:obj.value ?: @"" forKey:obj.name]; 31 | } 32 | }]; 33 | return [params copy]; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/QMUIBarProtocol/QMUIBarProtocolPrivate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // QMUIBarProtocolPrivate.h 10 | // QMUIKit 11 | // 12 | // Created by molice on 2022/5/18. 13 | // 14 | 15 | #import 16 | #import 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @protocol QMUIBarProtocolPrivate 21 | 22 | @required 23 | @property(nonatomic, assign) BOOL qmuibar_hasSetEffect; 24 | @property(nonatomic, assign) BOOL qmuibar_hasSetEffectForegroundColor; 25 | @property(nonatomic, strong, readonly, nullable) NSArray *qmuibar_backgroundEffects; 26 | - (void)qmuibar_updateEffect; 27 | @end 28 | 29 | @interface QMUIBarProtocolPrivate : NSObject 30 | 31 | + (void)swizzleBarBackgroundViewIfNeeded; 32 | @end 33 | 34 | NS_ASSUME_NONNULL_END 35 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/QMUIBarProtocol/UINavigationBar+QMUIBarProtocol.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // UINavigationBar+QMUIBarProtocol.h 10 | // QMUIKit 11 | // 12 | // Created by molice on 2022/5/18. 13 | // 14 | 15 | #import 16 | #import "QMUIBarProtocol.h" 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @interface UINavigationBar (QMUIBarProtocol) 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/QMUIBarProtocol/UITabBar+QMUIBarProtocol.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // UITabBar+QMUIBarProtocol.h 10 | // QMUIKit 11 | // 12 | // Created by molice on 2022/5/18. 13 | // 14 | 15 | #import 16 | #import "QMUIBarProtocol.h" 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @interface UITabBar (QMUIBarProtocol) 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/QMUIStringPrivate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // QMUIStringPrivate.h 10 | // QMUIKit 11 | // 12 | // Created by molice on 2021/11/5. 13 | // 14 | 15 | #import 16 | #import 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @interface QMUIStringPrivate : NSObject 21 | 22 | + (nullable id)substring:(id)aString avoidBreakingUpCharacterSequencesFromIndex:(NSUInteger)index lessValue:(BOOL)lessValue countingNonASCIICharacterAsTwo:(BOOL)countingNonASCIICharacterAsTwo; 23 | + (nullable id)substring:(id)aString avoidBreakingUpCharacterSequencesToIndex:(NSUInteger)index lessValue:(BOOL)lessValue countingNonASCIICharacterAsTwo:(BOOL)countingNonASCIICharacterAsTwo; 24 | + (nullable id)substring:(id)aString avoidBreakingUpCharacterSequencesWithRange:(NSRange)range lessValue:(BOOL)lessValue countingNonASCIICharacterAsTwo:(BOOL)countingNonASCIICharacterAsTwo; 25 | + (nullable id)string:(id)aString avoidBreakingUpCharacterSequencesByRemoveCharacterAtIndex:(NSUInteger)index; 26 | @end 27 | 28 | NS_ASSUME_NONNULL_END 29 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UIActivityIndicatorView+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UIActivityIndicatorView+QMUI.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 15/7/20. 14 | // 15 | 16 | #import 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | /** 21 | 内部通过重写系统方法来让 UIActivityIndicatorView 支持 setFrame: 方式修改尺寸,业务就像使用一个普通 UIView 一样去使用它即可。 22 | */ 23 | @interface UIActivityIndicatorView (QMUI) 24 | 25 | /// 内部转圈的那个 imageView 26 | @property(nonatomic, strong, readonly) UIImageView *qmui_animatingView; 27 | 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UIApplication+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // UIApplication+QMUI.h 10 | // QMUIKit 11 | // 12 | // Created by MoLice on 2021/8/30. 13 | // 14 | 15 | #import 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | @interface UIApplication (QMUI) 20 | 21 | /// 判断当前的 App 是否已经完全启动 22 | @property(nonatomic, assign, readonly) BOOL qmui_didFinishLaunching; 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UIApplication+QMUI.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // UIApplication+QMUI.m 10 | // QMUIKit 11 | // 12 | // Created by MoLice on 2021/8/30. 13 | // 14 | 15 | #import "UIApplication+QMUI.h" 16 | #import "QMUICore.h" 17 | 18 | @implementation UIApplication (QMUI) 19 | 20 | QMUISynthesizeBOOLProperty(qmui_didFinishLaunching, setQmui_didFinishLaunching) 21 | 22 | + (void)load { 23 | static dispatch_once_t onceToken; 24 | dispatch_once(&onceToken, ^{ 25 | OverrideImplementation(object_getClass(UIApplication.class), @selector(sharedApplication), ^id(__unsafe_unretained Class originClass, SEL originCMD, IMP (^originalIMPProvider)(void)) { 26 | return ^UIApplication *(UIApplication *selfObject) { 27 | // call super 28 | UIApplication * (*originSelectorIMP)(id, SEL); 29 | originSelectorIMP = (UIApplication * (*)(id, SEL))originalIMPProvider(); 30 | UIApplication * result = originSelectorIMP(selfObject, originCMD); 31 | 32 | if (![result qmui_getBoundBOOLForKey:@"QMUIAddedObserver"]) { 33 | [NSNotificationCenter.defaultCenter addObserver:result selector:@selector(qmui_handleDidFinishLaunchingNotification:) name:UIApplicationDidFinishLaunchingNotification object:nil]; 34 | [result qmui_bindBOOL:YES forKey:@"QMUIAddedObserver"]; 35 | } 36 | 37 | return result; 38 | }; 39 | }); 40 | }); 41 | } 42 | 43 | - (void)qmui_handleDidFinishLaunchingNotification:(NSNotification *)notification { 44 | self.qmui_didFinishLaunching = YES; 45 | [NSNotificationCenter.defaultCenter removeObserver:self name:UIApplicationDidFinishLaunchingNotification object:nil]; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UIBezierPath+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UIBezierPath+QMUI.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 16/8/9. 14 | // 15 | 16 | #import 17 | #import 18 | 19 | NS_ASSUME_NONNULL_BEGIN 20 | 21 | @interface UIBezierPath (QMUI) 22 | 23 | /** 24 | * 创建一条支持四个角的圆角值不相同的路径 25 | * @param rect 路径的rect 26 | * @param cornerRadius 圆角大小的数字,长度必须为4,顺序分别为[左上角、左下角、右下角、右上角] 27 | * @param lineWidth 描边的大小,如果不需要描边(例如path是用于fill而不是用于stroke),则填0 28 | */ 29 | + (instancetype)qmui_bezierPathWithRoundedRect:(CGRect)rect cornerRadiusArray:(NSArray *)cornerRadius lineWidth:(CGFloat)lineWidth; 30 | 31 | /** 32 | 创建一条尺寸为[0,1]的正方形区域内的曲线,曲线由 CAMediaTimingFunction 转换而来。如果希望得到不同尺寸的 path,请通过 -[UIBezierPath applyTransform:] 转换。 33 | */ 34 | + (instancetype)qmui_bezierPathWithMediaTimingFunction:(CAMediaTimingFunction *)function; 35 | @end 36 | 37 | NS_ASSUME_NONNULL_END 38 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UIBlurEffect+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // UIBlurEffect+QMUI.h 10 | // QMUIKit 11 | // 12 | // Created by MoLice on 2021/N/25. 13 | // 14 | 15 | #import 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | @interface UIBlurEffect (QMUI) 20 | 21 | /** 22 | 创建一个指定模糊半径的磨砂效果,注意这种方式创建的磨砂对象的 style 属性是无意义的(可以理解为系统的磨砂有两个维度:style、radius)。 23 | */ 24 | + (instancetype)qmui_effectWithBlurRadius:(CGFloat)radius; 25 | 26 | /** 27 | 获取当前 UIBlurEffect 的 style,前提是该 UIBlurEffect 对象是通过 effectWithStyle: 方式创建的。如果是通过指定 radius 方式创建的,则 qmui_style 会返回一个无意义的值。 28 | */ 29 | @property(nonatomic, assign, readonly) UIBlurEffectStyle qmui_style; 30 | 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UIBlurEffect+QMUI.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // UIBlurEffect+QMUI.m 10 | // QMUIKit 11 | // 12 | // Created by MoLice on 2021/N/25. 13 | // 14 | 15 | #import "UIBlurEffect+QMUI.h" 16 | #import "QMUICore.h" 17 | 18 | @implementation UIBlurEffect (QMUI) 19 | 20 | + (instancetype)qmui_effectWithBlurRadius:(CGFloat)radius { 21 | // -[UIBlurEffect effectWithBlurRadius:] 22 | UIBlurEffect *effect = [self qmui_performSelector:NSSelectorFromString(@"effectWithBlurRadius:") withArguments:&radius, nil]; 23 | return effect; 24 | } 25 | 26 | - (UIBlurEffectStyle)qmui_style { 27 | UIBlurEffectStyle style; 28 | // -[UIBlurEffect _style] 29 | [self qmui_performSelector:NSSelectorFromString(@"_style") withPrimitiveReturnValue:&style]; 30 | return style; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UIButton+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UIButton+QMUI.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 15/7/20. 14 | // 15 | 16 | #import 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @interface UIButton (QMUI) 21 | 22 | - (instancetype)qmui_initWithImage:(nullable UIImage *)image title:(nullable NSString *)title; 23 | 24 | /** 25 | * 在UIButton的样式(如字体)设置完后,将button的text设置为一个测试字符,再调用sizeToFit,从而令button的高度适应字体 26 | * @warning 会调用setText:forState:,因此请确保在设置完按钮的样式之后、设置text之前调用 27 | */ 28 | - (void)qmui_calculateHeightAfterSetAppearance; 29 | 30 | /** 31 | * 通过这个方法设置了 attributes 之后,setTitle:forState: 会自动把文字转成 attributedString 再添加上去,无需每次都自己构造 attributedString 32 | * @note 即使先调用 setTitle:forState: 然后再调用这个方法,之前的 title 仍然会被应用上这些 attributes 33 | * @note 该方法和 setTitleColor:forState: 均可设置字体颜色,如果二者冲突,则代码顺序较后的方法定义的颜色会最终生效 34 | * @note 如果包含了 NSKernAttributeName ,则此方法会自动帮你去掉最后一个字的 kern 效果,否则容易导致文字整体在视觉上不居中 35 | */ 36 | - (void)qmui_setTitleAttributes:(nullable NSDictionary *)attributes forState:(UIControlState)state; 37 | 38 | /** 39 | 为指定 state 的图片设置颜色,当使用这个方法时,会用 Core Graphic 将该状态的图片渲染成指定颜色,并修改 renderingMode 为 UIImageRenderingModeAlwaysOriginal,会有一定性能负担,所以只适用于小图场景。 40 | @param color 图片的颜色,为 nil 则清空之前为该 state 指定的 imageTintColor 41 | @param state 指定的状态 42 | @note 先 setImage 还是先 setImageTintColor,效果都是相同的 43 | */ 44 | - (void)qmui_setImageTintColor:(nullable UIColor *)color forState:(UIControlState)state; 45 | 46 | @end 47 | 48 | NS_ASSUME_NONNULL_END 49 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UICollectionView+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UICollectionView+QMUI.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 15/7/20. 14 | // 15 | 16 | #import 17 | #import 18 | 19 | @interface UICollectionView (QMUI) 20 | 21 | /** 22 | * 清除所有已选中的item的选中状态 23 | */ 24 | - (void)qmui_clearsSelection; 25 | 26 | /** 27 | * 重新`reloadData`,同时保持`reloadData`前item的选中状态 28 | */ 29 | - (void)qmui_reloadDataKeepingSelection; 30 | 31 | /** 32 | * 获取某个view在collectionView内对应的indexPath 33 | * 34 | * 例如某个view是某个cell里的subview,在这个view的点击事件回调方法里,就能通过`qmui_indexPathForItemAtView:`获取被点击的view所处的cell的indexPath 35 | * 36 | * @warning 注意返回的indexPath有可能为nil,要做保护。 37 | */ 38 | - (NSIndexPath *)qmui_indexPathForItemAtView:(id)sender; 39 | 40 | /** 41 | * 判断当前 indexPath 的 item 是否为可视的 item 42 | */ 43 | - (BOOL)qmui_itemVisibleAtIndexPath:(NSIndexPath *)indexPath; 44 | 45 | /** 46 | * 对系统的 indexPathsForVisibleItems 进行了排序后的结果 47 | */ 48 | - (NSArray *)qmui_indexPathsForVisibleItems; 49 | 50 | /** 51 | * 获取可视区域内第一个cell的indexPath。 52 | * 53 | * 为什么需要这个方法是因为系统的indexPathsForVisibleItems方法返回的数组成员是无序排列的,所以不能直接通过firstObject拿到第一个cell。 54 | * 55 | * @warning 若可视区域为CGRectZero,则返回nil 56 | */ 57 | - (NSIndexPath *)qmui_indexPathForFirstVisibleCell; 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UICollectionViewCell+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // UICollectionViewCell+QMUI.h 10 | // QMUIKit 11 | // 12 | // Created by MoLice on 2021/M/9. 13 | // 14 | 15 | #import 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | @interface UICollectionViewCell (QMUI) 20 | 21 | /// 设置 cell 点击时的背景色,如果没有 selectedBackgroundView 会创建一个。 22 | /// @warning 请勿再使用 self.selectedBackgroundView.backgroundColor 修改,因为 QMUITheme 里会重新应用 qmui_selectedBackgroundColor,会覆盖 self.selectedBackgroundView.backgroundColor 的效果。 23 | @property(nonatomic, strong, nullable) UIColor *qmui_selectedBackgroundColor; 24 | @end 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UICollectionViewCell+QMUI.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // UICollectionViewCell+QMUI.m 10 | // QMUIKit 11 | // 12 | // Created by MoLice on 2021/M/9. 13 | // 14 | 15 | #import "UICollectionViewCell+QMUI.h" 16 | #import "QMUICore.h" 17 | 18 | @interface UICollectionViewCell () 19 | @property(nonatomic, strong) UIView *qmuicvc_selectedBackgroundView; 20 | @end 21 | 22 | @implementation UICollectionViewCell (QMUI) 23 | 24 | QMUISynthesizeIdStrongProperty(qmuicvc_selectedBackgroundView, setQmuicvc_selectedBackgroundView) 25 | 26 | static char kAssociatedObjectKey_selectedBackgroundColor; 27 | - (void)setQmui_selectedBackgroundColor:(UIColor *)qmui_selectedBackgroundColor { 28 | objc_setAssociatedObject(self, &kAssociatedObjectKey_selectedBackgroundColor, qmui_selectedBackgroundColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 29 | if (qmui_selectedBackgroundColor && !self.selectedBackgroundView && !self.qmuicvc_selectedBackgroundView) { 30 | self.qmuicvc_selectedBackgroundView = UIView.new; 31 | self.selectedBackgroundView = self.qmuicvc_selectedBackgroundView; 32 | } 33 | if (self.qmuicvc_selectedBackgroundView) { 34 | self.qmuicvc_selectedBackgroundView.backgroundColor = qmui_selectedBackgroundColor; 35 | } 36 | } 37 | 38 | - (UIColor *)qmui_selectedBackgroundColor { 39 | return (UIColor *)objc_getAssociatedObject(self, &kAssociatedObjectKey_selectedBackgroundColor); 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UIGestureRecognizer+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UIGestureRecognizer+QMUI.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 2017/8/21. 14 | // 15 | 16 | #import 17 | 18 | @interface UIGestureRecognizer (QMUI) 19 | 20 | /// 获取当前手势直接作用到的 view(注意与 view 属性区分开:view 属性表示手势被添加到哪个 view 上,qmui_targetView 则是 view 属性里的某个 subview) 21 | @property(nullable, nonatomic, weak, readonly) UIView *qmui_targetView; 22 | @end 23 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UIImageView+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UIImageView+QMUI.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 16/8/9. 14 | // 15 | 16 | #import 17 | #import 18 | 19 | @interface UIImageView (QMUI) 20 | 21 | /** 22 | 暂停/恢复当前 UIImageView 上的 animation images(包括通过 animationImages 设置的图片数组,以及通过 [UIImage animatedImage] 系列方法创建的动图)的播放,默认为 NO。 23 | */ 24 | @property(nonatomic, assign) BOOL qmui_pause; 25 | 26 | /** 27 | 是否要用 QMUI 提供的高性能方式去渲染由 [UIImage animatedImage] 创建的 UIImage,(系统原生的方式在 UIImageView 被放在 UIScrollView 内时会卡顿),默认为 NO。 28 | */ 29 | @property(nonatomic, assign) BOOL qmui_smoothAnimation; 30 | 31 | /** 32 | * 把 UIImageView 的宽高调整为能保持 image 宽高比例不变的同时又不超过给定的 `limitSize` 大小的最大frame 33 | * 34 | * 建议在设置完x/y之后调用 35 | */ 36 | - (void)qmui_sizeToFitKeepingImageAspectRatioInSize:(CGSize)limitSize; 37 | @end 38 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UIMenuController+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // UIMenuController+QMUI.h 10 | // QMUIKit 11 | // 12 | // Created by 陈志宏 on 2019/7/21. 13 | // 14 | 15 | #import 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | @interface UIMenuController (QMUI) 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UINavigationBar+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UINavigationBar+QMUI.h 11 | // QMUIKit 12 | // 13 | // Created by QMUI Team on 2018/O/8. 14 | // 15 | 16 | #import 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @interface UINavigationBar (QMUI) 21 | 22 | /** 23 | UINavigationBar 在 iOS 11 下所有的 item 都会由 contentView 管理,只要在 UINavigationController init 完成后就能拿到 qmui_contentView 的值 24 | */ 25 | @property(nonatomic, strong, readonly, nullable) UIView *qmui_contentView; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UINavigationItem+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UINavigationItem+QMUI.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 2020/10/28. 14 | // 15 | 16 | #import 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @interface UINavigationItem (QMUI) 21 | 22 | @property(nonatomic, weak, readonly, nullable) UINavigationBar *qmui_navigationBar; 23 | @property(nonatomic, weak, readonly, nullable) UINavigationController *qmui_navigationController; 24 | @property(nonatomic, weak, readonly, nullable) UIViewController *qmui_viewController; 25 | @property(nonatomic, weak, readonly, nullable) UINavigationItem *qmui_previousItem; 26 | @property(nonatomic, weak, readonly, nullable) UINavigationItem *qmui_nextItem; 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UISearchController+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // UISearchController+QMUI.h 10 | // QMUIKit 11 | // 12 | // Created by ziezheng on 2019/9/27. 13 | // 14 | 15 | #import 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | @interface UISearchController (QMUI) 20 | 21 | /// 系统默认是只有搜索框文本不为空时才会显示搜索结果,将该属性置为 YES 可以做到只要 active 就能显示搜索结果列表。 22 | /// 该属性与 qmui_launchView、obscuresBackgroundDuringPresentation 互斥,打开该属性时会强制清除互斥属性(但如果你非要在打开该属性之后,再重新为这两个互斥属性赋值,也是可以的)。 23 | /// 默认为 NO。 24 | @property(nonatomic, assign) BOOL qmui_alwaysShowSearchResultsController; 25 | 26 | /// 当 A 里构造了一个 UISearchController(称为B),当B进入搜索状态后,再 push/present 到其他界面,B的 viewWillAppear: 等生命周期方法并不会被调用,但A的生命周期方法会被调用,这令搜索业务难以感知当前的界面状态。 27 | /// 若将当前属性置为 YES,则会保证A的生命周期方法被调用时也触发B的生命周期方法。 28 | /// 默认为 NO。 29 | @property(nonatomic, assign) BOOL qmui_forwardAppearanceMethodsFromPresentingController; 30 | 31 | /// 升起键盘时的半透明遮罩,nil 表示用系统的,非 nil 则用自己的。默认为 nil。 32 | /// @note 如果使用了 launchView 则该属性无效。 33 | @property(nonatomic, strong, nullable) UIColor *qmui_dimmingColor; 34 | 35 | /// 在搜索文字为空时会展示的一个 view,通常用于实现“最近搜索”之类的功能。launchView 最终会被布局为撑满搜索框以下的所有空间。 36 | @property(nonatomic, strong, nullable) UIView *qmui_launchView; 37 | 38 | /// 获取进入搜索状态后 searchBar 在 UISearchController.view 坐标系内的 maxY 值,方便 searchResultsController 布局。 39 | @property(nonatomic, assign, readonly) CGFloat qmui_searchBarMaxY; 40 | @end 41 | 42 | NS_ASSUME_NONNULL_END 43 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UISwitch+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // UISwitch+QMUI.h 10 | // QMUIKit 11 | // 12 | // Created by MoLice on 2019/7/12. 13 | // 14 | 15 | #import 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | @interface UISwitch (QMUI) 20 | 21 | /// 用于设置 UISwitch 关闭时的背景色(除了圆点外的其他颜色) 22 | @property(nonatomic, strong) UIColor *qmui_offTintColor; 23 | 24 | @end 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UITabBar+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UITabBar+QMUI.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 2017/2/14. 14 | // 15 | 16 | #import 17 | #import "QMUIBarProtocol.h" 18 | 19 | NS_ASSUME_NONNULL_BEGIN 20 | 21 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 22 | 23 | UIKIT_EXTERN API_AVAILABLE(ios(13.0), tvos(13.0)) @interface UITabBarAppearance (QMUI) 24 | 25 | /** 26 | 同时设置 stackedLayoutAppearance、inlineLayoutAppearance、compactInlineLayoutAppearance 三个状态下的 itemAppearance 27 | */ 28 | - (void)qmui_applyItemAppearanceWithBlock:(void (^)(UITabBarItemAppearance *itemAppearance))block; 29 | @end 30 | 31 | #endif 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UITabBarItem+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UITabBarItem+QMUI.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 15/7/20. 14 | // 15 | 16 | #import 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @interface UITabBarItem (QMUI) 21 | 22 | /** 23 | * 双击 tabBarItem 时的回调,默认为 nil。 24 | * @param tabBarItem 被双击的 UITabBarItem,若需要拿到当前的 view 则通过 qmui_view 获取。 25 | * @param index 被双击的 UITabBarItem 的序号 26 | */ 27 | @property(nonatomic, copy, nullable) void (^qmui_doubleTapBlock)(UITabBarItem *tabBarItem, NSInteger index); 28 | 29 | /** 30 | * 获取一个UITabBarItem内显示图标的UIImageView,如果找不到则返回nil 31 | */ 32 | - (nullable UIImageView *)qmui_imageView; 33 | + (nullable UIImageView *)qmui_imageViewInTabBarButton:(nullable UIView *)tabBarButton; 34 | 35 | @end 36 | 37 | NS_ASSUME_NONNULL_END 38 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UITabBarItem+QMUI.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UITabBarItem+QMUI.m 11 | // qmui 12 | // 13 | // Created by QMUI Team on 15/7/20. 14 | // 15 | 16 | #import "UITabBarItem+QMUI.h" 17 | #import "QMUICore.h" 18 | #import "UIBarItem+QMUI.h" 19 | 20 | @implementation UITabBarItem (QMUI) 21 | 22 | QMUISynthesizeIdCopyProperty(qmui_doubleTapBlock, setQmui_doubleTapBlock) 23 | 24 | - (UIImageView *)qmui_imageView { 25 | return [self.class qmui_imageViewInTabBarButton:self.qmui_view]; 26 | } 27 | 28 | + (UIImageView *)qmui_imageViewInTabBarButton:(UIView *)tabBarButton { 29 | 30 | if (!tabBarButton) { 31 | return nil; 32 | } 33 | return [tabBarButton qmui_valueForKey:@"_imageView"]; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UITableViewHeaderFooterView+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UITableViewHeaderFooterView+QMUI.h 11 | // QMUIKit 12 | // 13 | // Created by MoLice on 2020/6/4. 14 | // 15 | 16 | #import 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @interface UITableViewHeaderFooterView (QMUI) 21 | 22 | @property(nonatomic, weak, readonly) UITableView *qmui_tableView; 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UITableViewHeaderFooterView+QMUI.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UITableViewHeaderFooterView+QMUI.m 11 | // QMUIKit 12 | // 13 | // Created by MoLice on 2020/6/4. 14 | // 15 | 16 | #import "UITableViewHeaderFooterView+QMUI.h" 17 | #import "QMUICore.h" 18 | #import "UITableView+QMUI.h" 19 | #import "UIView+QMUI.h" 20 | 21 | @implementation UITableViewHeaderFooterView (QMUI) 22 | 23 | - (UITableView *)qmui_tableView { 24 | return [self valueForKey:@"tableView"]; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UITextField+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UITextField+QMUI.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 2017/3/29. 14 | // 15 | 16 | #import 17 | #import 18 | 19 | NS_ASSUME_NONNULL_BEGIN 20 | 21 | @interface UITextField (QMUI) 22 | 23 | /// UITextView 在输入框开头继续按删除按键,也会触发 shouldChange 的 delegate,但 UITextField 没这个行为,所以提供这个属性,当置为 YES 时,行为与 UITextView 一致,在输入框开头删除也会询问 delegate 并传 range(0, 0) 和空的 text。 24 | /// 默认为 NO。 25 | @property(nonatomic, assign) BOOL qmui_respondsToDeleteActionAtLeading; 26 | 27 | /// UITextField 只有 selectedTextRange 属性(在 UITextInput 协议里定义),相对而言没有 NSRange 那么直观,因此这里提供 NSRange 类型的操作方式可以主动设置光标的位置或选中的区域 28 | @property(nonatomic, assign) NSRange qmui_selectedRange; 29 | 30 | /// 输入框右边的 clearButton,在 UITextField 初始化后就存在 31 | @property(nullable, nonatomic, weak, readonly) UIButton *qmui_clearButton; 32 | 33 | /// 自定义 clearButton 的图片,设置成nil,恢复到系统默认的图片 34 | @property(nullable, nonatomic, strong) UIImage *qmui_clearButtonImage UI_APPEARANCE_SELECTOR; 35 | 36 | /** 37 | * convert UITextRange to NSRange, for example, [self qmui_convertNSRangeFromUITextRange:self.markedTextRange] 38 | */ 39 | - (NSRange)qmui_convertNSRangeFromUITextRange:(UITextRange *)textRange; 40 | 41 | /** 42 | * convert NSRange to UITextRange 43 | * @return return nil if range is invalidate. 44 | */ 45 | - (nullable UITextRange *)qmui_convertUITextRangeFromNSRange:(NSRange)range; 46 | 47 | @end 48 | 49 | NS_ASSUME_NONNULL_END 50 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UITextInputTraits+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // UITextInputTraits+QMUI.h 10 | // QMUIKit 11 | // 12 | // Created by MoLice on 2019/O/16. 13 | // 14 | 15 | #import 16 | 17 | @interface NSObject (QMUITextInput) 18 | 19 | @end 20 | 21 | @interface NSObject (QMUITextInput_Private) 22 | 23 | /// 内部使用,标记某次 keyboardAppearance 的改动是由于 UIView+QMUITheme 内导致的,而非用户手动修改 24 | @property(nonatomic, assign) UIKeyboardAppearance qmui_keyboardAppearance; 25 | 26 | /// 内部使用,用于标志业务自己修改了 keyboardAppearance 的情况 27 | @property(nonatomic, assign) BOOL qmui_hasCustomizedKeyboardAppearance; 28 | @end 29 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UITextView+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UITextView+QMUI.h 11 | // qmui 12 | // 13 | // Created by QMUI Team on 2017/3/29. 14 | // 15 | 16 | #import 17 | #import 18 | 19 | NS_ASSUME_NONNULL_BEGIN 20 | 21 | @interface UITextView (QMUI) 22 | 23 | /** 24 | 立即刷新当前的 contentSize 25 | */ 26 | - (void)qmui_updateContentSize; 27 | 28 | /** 29 | * UITextView 只有 selectedTextRange 属性(在协议里定义),这里拓展了一个方法可以将 UITextRange 类型的 selectedTextRange 转换为 NSRange 类型的 selectedRange 30 | */ 31 | @property(nonatomic, assign, readonly) NSRange qmui_selectedRange; 32 | 33 | /** 34 | * convert UITextRange to NSRange, for example, [self qmui_convertNSRangeFromUITextRange:self.markedTextRange] 35 | */ 36 | - (NSRange)qmui_convertNSRangeFromUITextRange:(UITextRange *)textRange; 37 | 38 | /** 39 | * convert NSRange to UITextRange 40 | * @return return nil if range is invalidate. 41 | */ 42 | - (nullable UITextRange *)qmui_convertUITextRangeFromNSRange:(NSRange)range; 43 | 44 | /** 45 | * 设置 text 会让 selectedTextRange 跳到最后一个字符,导致在中间修改文字后光标会跳到末尾,所以设置前要保存一下,设置后恢复过来 46 | */ 47 | - (void)qmui_setTextKeepingSelectedRange:(NSString *)text; 48 | 49 | /** 50 | * 设置 attributedText 会让 selectedTextRange 跳到最后一个字符,导致在中间修改文字后光标会跳到末尾,所以设置前要保存一下,设置后恢复过来 51 | */ 52 | - (void)qmui_setAttributedTextKeepingSelectedRange:(NSAttributedString *)attributedText; 53 | 54 | /** 55 | [UITextView scrollRangeToVisible:] 并不会考虑 textContainerInset.bottom,所以使用这个方法来代替 56 | 57 | @param range 要滚动到的文字区域,如果 range 非法则什么都不做 58 | */ 59 | - (void)qmui_scrollRangeToVisible:(NSRange)range; 60 | 61 | /** 62 | * 将光标滚到可视区域 63 | */ 64 | - (void)qmui_scrollCaretVisibleAnimated:(BOOL)animated; 65 | 66 | @end 67 | 68 | NS_ASSUME_NONNULL_END 69 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UIToolbar+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // UIToolbar+QMUI.h 10 | // QMUIKit 11 | // 12 | // Created by MoLice on 2021/N/24. 13 | // 14 | 15 | #import 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | @interface UIToolbar (QMUI) 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UITraitCollection+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // UITraitCollection+QMUI.h 10 | // QMUIKit 11 | // 12 | // Created by ziezheng on 2019/7/19. 13 | // 14 | 15 | 16 | #import 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | 21 | @interface UITraitCollection (QMUI) 22 | 23 | /** 24 | 添加一个系统的深色、浅色外观发即将生变化前的监听,可用于需要在外观即将发生改变之前更新状态,例如 QMUIThemeManager 利用其来自动切换主题 25 | @note 如果在 info.plist 中指定 User Interface Style 值将无法监听。 26 | */ 27 | + (void)qmui_addUserInterfaceStyleWillChangeObserver:(id)observer selector:(SEL)aSelector API_AVAILABLE(ios(13.0)); 28 | 29 | @end 30 | 31 | 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /QMUIKit/UIKitExtensions/UIVisualEffectView+QMUI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // UIVisualEffectView+QMUI.h 11 | // QMUIKit 12 | // 13 | // Created by MoLice on 2020/7/15. 14 | // 15 | 16 | #import 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | @interface UIVisualEffectView (QMUI) 21 | 22 | /** 23 | 系统的 UIVisualEffectView 会为不同的 effect 生成不同的 subview 并为其设置对应的 backgroundColor、alpha,这些 subview 的样式我们是修改不了的,如果有设计需求希望在磨砂上方盖一层前景色来调整磨砂效果,总是会受自带的 subview 的影响(例如无法有特别明显的磨砂效果,因为自带的 subview alpha 可能很高,透不过去),因此增加这个属性,当设置一个非 nil 的颜色后,会强制把系统自带的 subview 隐藏掉,只显示你自己的 foregroundColor,从而实现精准的调整。 24 | 25 | 以 UINavigationBar 为例,当我们通过 UINavigationBar.barTintColor 或者 UINavigationBarAppearance.backgroundEffect/backgroundColor 实现磨砂效果时,我们设置上去的 barTintColor 最终会被系统进行一些运算后产生另一个色值,最终显示出来的色值和我们设置的 barTintColor 是相似但不相等的,如果希望有精准的色值调整,就可以自己获取 UINavigationBar 内部的 UIVisualEffectView,再修改它的 qmui_foregroundColor。 26 | 27 | @note 注意这个颜色需要是半透明的,才能透出背后的磨砂,如果设置不透明的色值,就失去了磨砂效果了。 28 | @note 注意如果开启了系统的“降低透明度”辅助功能开关,此时 qmui_foregroundColor 的效果会变得比较怪异,因此默认会监听 UIAccessibilityIsReduceTransparencyEnabled 的变化,当开启时会强制把 qmui_foregroundColor 改为不透明的,从而屏蔽磨砂的效果。 29 | */ 30 | @property(nonatomic, strong, nullable) UIColor *qmui_foregroundColor; 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /QMUIKitTests/Core/QMUICommonDefinesTests.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | // 10 | // QMUICommonDefinesTests.m 11 | // QMUIKitTests 12 | // 13 | // Created by MoLice on 2020/5/12. 14 | // 15 | 16 | #import 17 | #import 18 | 19 | @interface QMUICommonDefinesTests : XCTestCase 20 | 21 | @end 22 | 23 | @implementation QMUICommonDefinesTests 24 | 25 | - (void)testCGFloatCalcOperator { 26 | CGFloat a = 0.999; 27 | CGFloat b = 1.011; 28 | CGFloat c = 1.033; 29 | CGFloat d = 1.099; 30 | 31 | XCTAssertTrue(CGFloatEqualToFloat(a, b)); 32 | XCTAssertTrue(CGFloatEqualToFloat(b, c)); 33 | XCTAssertTrue(CGFloatEqualToFloat(c, d)); 34 | 35 | XCTAssertTrue(CGFloatEqualToFloatWithPrecision(a, b, 1)); 36 | XCTAssertTrue(CGFloatEqualToFloatWithPrecision(b, c, 1)); 37 | XCTAssertFalse(CGFloatEqualToFloatWithPrecision(c, d, 1)); 38 | 39 | XCTAssertFalse(CGFloatEqualToFloatWithPrecision(a, b, 2)); 40 | XCTAssertFalse(CGFloatEqualToFloatWithPrecision(b, c, 2)); 41 | XCTAssertFalse(CGFloatEqualToFloatWithPrecision(c, d, 2)); 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /QMUIKitTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /QMUIKitTests/UIKitExtensions/NSObjectTests.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | // 9 | // NSObject.m 10 | // QMUIKitTests 11 | // 12 | // Created by MoLice on 2019/J/5. 13 | // 14 | 15 | #import 16 | #import 17 | 18 | @interface NSObjectTests : XCTestCase 19 | 20 | @end 21 | 22 | @implementation NSObjectTests 23 | 24 | - (void)testValueForKey { 25 | UINavigationBar *navigationBar = [UINavigationBar new]; 26 | [navigationBar sizeToFit]; 27 | XCTAssertTrue(navigationBar.qmui_backgroundView); 28 | XCTAssertFalse(navigationBar.qmui_shadowImageView); 29 | 30 | UITabBar *tabBar = [UITabBar new]; 31 | [tabBar sizeToFit]; 32 | XCTAssertTrue(tabBar.qmui_backgroundView); 33 | XCTAssertFalse(tabBar.qmui_shadowImageView); 34 | 35 | UISearchBar *searchBar = [UISearchBar new]; 36 | searchBar.scopeButtonTitles = @[@"A", @"B"]; 37 | searchBar.showsCancelButton = YES; 38 | [searchBar sizeToFit]; 39 | [searchBar qmui_setValue:@"Test" forKey:@"_cancelButtonText"]; 40 | // iOS13 crash : [searchBar setValue:@"Test" forKey:@"_cancelButtonText"]; 41 | UIView *searchField = [searchBar qmui_valueForKey:@"_searchField"]; 42 | // iOS13 crash : [searchBar valueForKey:@"_searchField"]; 43 | 44 | XCTAssertTrue(searchBar.qmui_backgroundView); 45 | XCTAssertTrue(searchBar.qmui_cancelButton); 46 | XCTAssertTrue(searchBar.qmui_segmentedControl); 47 | XCTAssertFalse([searchBar qmui_valueForKey:@"_searchController"]); 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /new_license_content.txt: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | -------------------------------------------------------------------------------- /old_license_content.txt: -------------------------------------------------------------------------------- 1 | /** 2 | * Tencent is pleased to support the open source community by making QMUI_iOS available. 3 | * Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved. 4 | * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 5 | * http://opensource.org/licenses/MIT 6 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 7 | */ 8 | -------------------------------------------------------------------------------- /qmui.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /qmui.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /qmui.xcodeproj/project.xcworkspace/xcuserdata/molice.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tencent/QMUI_iOS/4dca2347dcb5feecdbb39fc99b36004c8c94a958/qmui.xcodeproj/project.xcworkspace/xcuserdata/molice.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /qmui.xcodeproj/xcshareddata/xcschemes/QMUIKitTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 14 | 15 | 17 | 23 | 24 | 25 | 26 | 27 | 37 | 38 | 44 | 45 | 47 | 48 | 51 | 52 | 53 | --------------------------------------------------------------------------------