Commit 78114b96 authored by jinzhu's avatar jinzhu

add .ios

parent a803decc
#include "Flutter.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "../Flutter/Generated.xcconfig"
ENABLE_BITCODE=NO
#include "Flutter.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
FLUTTER_BUILD_MODE=release
/Users/mac/development/flutter/.pub-cache/git/flutter_boost-3978c43c31c1c29b569724fd330b367caa459acc
\ No newline at end of file
/Users/mac/development/flutter/.pub-cache/git/native_flutter_transfer_plugin-280d323852a6ba68678e5f9962dbe36d85526cee
\ No newline at end of file
/Users/mac/development/flutter/.pub-cache/hosted/pub.flutter-io.cn/xservice_kit-0.0.29
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>8.0</string>
</dict>
</plist>
//
// Generated file. Do not edit.
//
#ifndef GeneratedPluginRegistrant_h
#define GeneratedPluginRegistrant_h
#import <Flutter/Flutter.h>
@interface GeneratedPluginRegistrant : NSObject
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry;
@end
#endif /* GeneratedPluginRegistrant_h */
//
// Generated file. Do not edit.
//
#import "GeneratedPluginRegistrant.h"
#import <flutter_boost/FlutterBoostPlugin.h>
#import <native_flutter_transfer_plugin/NativeFlutterTransferPlugin.h>
#import <xservice_kit/XserviceKitPlugin.h>
@implementation GeneratedPluginRegistrant
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry {
[FlutterBoostPlugin registerWithRegistrar:[registry registrarForPlugin:@"FlutterBoostPlugin"]];
[NativeFlutterTransferPlugin registerWithRegistrar:[registry registrarForPlugin:@"NativeFlutterTransferPlugin"]];
[XserviceKitPlugin registerWithRegistrar:[registry registrarForPlugin:@"XserviceKitPlugin"]];
}
@end
#
# Generated file, do not edit.
#
Pod::Spec.new do |s|
s.name = 'FlutterPluginRegistrant'
s.version = '0.0.1'
s.summary = 'Registers plugins with your flutter app'
s.description = <<-DESC
Depends on all your plugins, and provides a function to register them.
DESC
s.homepage = 'https://flutter.dev'
s.license = { :type => 'BSD' }
s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
s.ios.deployment_target = '8.0'
s.source_files = "Classes", "Classes/**/*.{h,m}"
s.source = { :path => '.' }
s.public_header_files = './Classes/**/*.h'
s.dependency 'Flutter'
s.dependency 'flutter_boost'
s.dependency 'native_flutter_transfer_plugin'
s.dependency 'xservice_kit'
end
// This is a generated file; do not edit or check into version control.
FLUTTER_ROOT=/Users/mac/development/flutter
FLUTTER_APPLICATION_PATH=/Users/mac/code/GMAlpha/gmalpha_flutter
FLUTTER_TARGET=/Users/mac/code/GMAlpha/gmalpha_flutter/lib/main.dart
FLUTTER_BUILD_DIR=build
SYMROOT=${SOURCE_ROOT}/../build/ios
FLUTTER_BUILD_NAME=1.0.0
FLUTTER_BUILD_NUMBER=1
This directory contains support code for embedding the Flutter project in an iOS app.
It should not be edited or checked in.
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_FLUTTER_H_
#define FLUTTER_FLUTTER_H_
/**
BREAKING CHANGES:
December 17, 2018:
- Changed designated initializer on FlutterEngine
October 5, 2018:
- Removed FlutterNavigationController.h/.mm
- Changed return signature of `FlutterDartHeadlessCodeRunner.run*` from void
to bool
- Removed HeadlessPlatformViewIOS
- Marked FlutterDartHeadlessCodeRunner deprecated
August 31, 2018: Marked -[FlutterDartProject
initFromDefaultSourceForConfiguration] and FlutterStandardBigInteger as
unavailable.
July 26, 2018: Marked -[FlutterDartProject
initFromDefaultSourceForConfiguration] deprecated.
February 28, 2018: Removed "initWithFLXArchive" and
"initWithFLXArchiveWithScriptSnapshot".
January 15, 2018: Marked "initWithFLXArchive" and
"initWithFLXArchiveWithScriptSnapshot" as unavailable following the
deprecation from December 11, 2017. Scheduled to be removed on February
19, 2018.
January 09, 2018: Deprecated "FlutterStandardBigInteger" and its use in
"FlutterStandardMessageCodec" and "FlutterStandardMethodCodec". Scheduled to
be marked as unavailable once the deprecation has been available on the
flutter/flutter alpha branch for four weeks. "FlutterStandardBigInteger" was
needed because the Dart 1.0 int type had no size limit. With Dart 2.0, the
int type is a fixed-size, 64-bit signed integer. If you need to communicate
larger integers, use NSString encoding instead.
December 11, 2017: Deprecated "initWithFLXArchive" and
"initWithFLXArchiveWithScriptSnapshot" and scheculed the same to be marked as
unavailable on January 15, 2018. Instead, "initWithFlutterAssets" and
"initWithFlutterAssetsWithScriptSnapshot" should be used. The reason for this
change is that the FLX archive will be deprecated and replaced with a flutter
assets directory containing the same files as the FLX did.
November 29, 2017: Added a BREAKING CHANGES section.
*/
#include "FlutterAppDelegate.h"
#include "FlutterBinaryMessenger.h"
#include "FlutterCallbackCache.h"
#include "FlutterChannels.h"
#include "FlutterCodecs.h"
#include "FlutterDartProject.h"
#include "FlutterEngine.h"
#include "FlutterHeadlessDartRunner.h"
#include "FlutterMacros.h"
#include "FlutterPlatformViews.h"
#include "FlutterPlugin.h"
#include "FlutterPluginAppLifeCycleDelegate.h"
#include "FlutterTexture.h"
#include "FlutterViewController.h"
#endif // FLUTTER_FLUTTER_H_
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_FLUTTERAPPDELEGATE_H_
#define FLUTTER_FLUTTERAPPDELEGATE_H_
#import <UIKit/UIKit.h>
#include "FlutterMacros.h"
#include "FlutterPlugin.h"
/**
* `UIApplicationDelegate` subclass for simple apps that want default behavior.
*
* This class implements the following behaviors:
* * Status bar touches are forwarded to the key window's root view
* `FlutterViewController`, in order to trigger scroll to top.
* * Keeps the Flutter connection open in debug mode when the phone screen
* locks.
*
* App delegates for Flutter applications are *not* required to inherit from
* this class. Developers of custom app delegate classes should copy and paste
* code as necessary from FlutterAppDelegate.mm.
*/
FLUTTER_EXPORT
@interface FlutterAppDelegate
: UIResponder <UIApplicationDelegate, FlutterPluginRegistry, FlutterAppLifeCycleProvider>
@property(strong, nonatomic) UIWindow* window;
@end
#endif // FLUTTER_FLUTTERDARTPROJECT_H_
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_FLUTTERBINARYMESSENGER_H_
#define FLUTTER_FLUTTERBINARYMESSENGER_H_
#import <Foundation/Foundation.h>
#include "FlutterMacros.h"
NS_ASSUME_NONNULL_BEGIN
/**
* A message reply callback.
*
* Used for submitting a binary reply back to a Flutter message sender. Also used
* in for handling a binary message reply received from Flutter.
*
* @param reply The reply.
*/
typedef void (^FlutterBinaryReply)(NSData* _Nullable reply);
/**
* A strategy for handling incoming binary messages from Flutter and to send
* asynchronous replies back to Flutter.
*
* @param message The message.
* @param reply A callback for submitting an asynchronous reply to the sender.
*/
typedef void (^FlutterBinaryMessageHandler)(NSData* _Nullable message, FlutterBinaryReply reply);
/**
* A facility for communicating with the Flutter side using asynchronous message
* passing with binary messages.
*
* Implementated by:
* - `FlutterBasicMessageChannel`, which supports communication using structured
* messages.
* - `FlutterMethodChannel`, which supports communication using asynchronous
* method calls.
* - `FlutterEventChannel`, which supports commuication using event streams.
*/
FLUTTER_EXPORT
@protocol FlutterBinaryMessenger <NSObject>
/**
* Sends a binary message to the Flutter side on the specified channel, expecting
* no reply.
*
* @param channel The channel name.
* @param message The message.
*/
- (void)sendOnChannel:(NSString*)channel message:(NSData* _Nullable)message;
/**
* Sends a binary message to the Flutter side on the specified channel, expecting
* an asynchronous reply.
*
* @param channel The channel name.
* @param message The message.
* @param callback A callback for receiving a reply.
*/
- (void)sendOnChannel:(NSString*)channel
message:(NSData* _Nullable)message
binaryReply:(FlutterBinaryReply _Nullable)callback
// TODO: Add macOS support for replies once
// https://github.com/flutter/flutter/issues/18852 is fixed.
API_UNAVAILABLE(macos);
/**
* Registers a message handler for incoming binary messages from the Flutter side
* on the specified channel.
*
* Replaces any existing handler. Use a `nil` handler for unregistering the
* existing handler.
*
* @param channel The channel name.
* @param handler The message handler.
*/
- (void)setMessageHandlerOnChannel:(NSString*)channel
binaryMessageHandler:(FlutterBinaryMessageHandler _Nullable)handler;
@end
NS_ASSUME_NONNULL_END
#endif // FLUTTER_FLUTTERBINARYMESSENGER_H_
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_FLUTTERCALLBACKCACHE_H_
#define FLUTTER_FLUTTERCALLBACKCACHE_H_
#import <Foundation/Foundation.h>
#include "FlutterMacros.h"
/**
* An object containing the result of `FlutterCallbackCache`'s `lookupCallbackInformation`
* method.
*/
FLUTTER_EXPORT
@interface FlutterCallbackInformation : NSObject
/**
* The name of the callback.
*/
@property(retain) NSString* callbackName;
/**
* The class name of the callback.
*/
@property(retain) NSString* callbackClassName;
/**
* The library path of the callback.
*/
@property(retain) NSString* callbackLibraryPath;
@end
/**
* The cache containing callback information for spawning a
* `FlutterHeadlessDartRunner`.
*/
FLUTTER_EXPORT
@interface FlutterCallbackCache : NSObject
/**
* Returns the callback information for the given callback handle.
* This callback information can be used when spawning a
* `FlutterHeadlessDartRunner`.
*
* @param handle The handle for a callback, provided by the
* Dart method `PluginUtilities.getCallbackHandle`.
* @return A `FlutterCallbackInformation` object which contains the name of the
* callback, the name of the class in which the callback is defined, and the
* path of the library which contains the callback. If the provided handle is
* invalid, nil is returned.
*/
+ (FlutterCallbackInformation*)lookupCallbackInformation:(int64_t)handle;
@end
#endif // FLUTTER_FLUTTERCALLBACKCACHE_H_
This diff is collapsed.
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_FLUTTERDARTPROJECT_H_
#define FLUTTER_FLUTTERDARTPROJECT_H_
#import <Foundation/Foundation.h>
#include "FlutterMacros.h"
/**
* A set of Flutter and Dart assets used by a `FlutterEngine` to initialize execution.
*/
FLUTTER_EXPORT
@interface FlutterDartProject : NSObject
/**
* Initializes a Flutter Dart project from a bundle.
*/
- (instancetype)initWithPrecompiledDartBundle:(NSBundle*)bundle NS_DESIGNATED_INITIALIZER;
/**
* Unavailable - use `init` instead.
*/
- (instancetype)initFromDefaultSourceForConfiguration FLUTTER_UNAVAILABLE("Use -init instead.");
/**
* Returns the file name for the given asset. If the bundle with the identifier
* "io.flutter.flutter.app" exists, it will try use that bundle; otherwise, it
* will use the main bundle. To specify a different bundle, use
* `-lookupKeyForAsset:asset:fromBundle`.
*
* @param asset The name of the asset. The name can be hierarchical.
* @return the file name to be used for lookup in the main bundle.
*/
+ (NSString*)lookupKeyForAsset:(NSString*)asset;
/**
* Returns the file name for the given asset.
* The returned file name can be used to access the asset in the supplied bundle.
*
* @param asset The name of the asset. The name can be hierarchical.
* @param bundle The `NSBundle` to use for looking up the asset.
* @return the file name to be used for lookup in the main bundle.
*/
+ (NSString*)lookupKeyForAsset:(NSString*)asset fromBundle:(NSBundle*)bundle;
/**
* Returns the file name for the given asset which originates from the specified package.
* The returned file name can be used to access the asset in the application's main bundle.
*
* @param asset The name of the asset. The name can be hierarchical.
* @param package The name of the package from which the asset originates.
* @return the file name to be used for lookup in the main bundle.
*/
+ (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package;
/**
* Returns the file name for the given asset which originates from the specified package.
* The returned file name can be used to access the asset in the specified bundle.
*
* @param asset The name of the asset. The name can be hierarchical.
* @param package The name of the package from which the asset originates.
* @param bundle The bundle to use when doing the lookup.
* @return the file name to be used for lookup in the main bundle.
*/
+ (NSString*)lookupKeyForAsset:(NSString*)asset
fromPackage:(NSString*)package
fromBundle:(NSBundle*)bundle;
/**
* Returns the default identifier for the bundle where we expect to find the Flutter Dart
* application.
*/
+ (NSString*)defaultBundleIdentifier;
@end
#endif // FLUTTER_FLUTTERDARTPROJECT_H_
This diff is collapsed.
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_FLUTTERHEADLESSDARTRUNNER_H_
#define FLUTTER_FLUTTERHEADLESSDARTRUNNER_H_
#import <Foundation/Foundation.h>
#include "FlutterBinaryMessenger.h"
#include "FlutterDartProject.h"
#include "FlutterEngine.h"
#include "FlutterMacros.h"
/**
* A callback for when FlutterHeadlessDartRunner has attempted to start a Dart
* Isolate in the background.
*
* @param success YES if the Isolate was started and run successfully, NO
* otherwise.
*/
typedef void (^FlutterHeadlessDartRunnerCallback)(BOOL success);
/**
* The FlutterHeadlessDartRunner runs Flutter Dart code with a null rasterizer,
* and no native drawing surface. It is appropriate for use in running Dart
* code e.g. in the background from a plugin.
*
* Most callers should prefer using `FlutterEngine` directly; this interface exists
* for legacy support.
*/
FLUTTER_EXPORT
FLUTTER_DEPRECATED("FlutterEngine should be used rather than FlutterHeadlessDartRunner")
@interface FlutterHeadlessDartRunner : FlutterEngine
/**
* Iniitalize this FlutterHeadlessDartRunner with a `FlutterDartProject`.
*
* If the FlutterDartProject is not specified, the FlutterHeadlessDartRunner will attempt to locate
* the project in a default location.
*
* A newly initialized engine will not run the `FlutterDartProject` until either
* `-runWithEntrypoint:` or `-runWithEntrypoint:libraryURI` is called.
*
* @param labelPrefix The label prefix used to identify threads for this instance. Should
* be unique across FlutterEngine instances
* @param projectOrNil The `FlutterDartProject` to run.
*/
- (instancetype)initWithName:(NSString*)labelPrefix project:(FlutterDartProject*)projectOrNil;
/**
* Iniitalize this FlutterHeadlessDartRunner with a `FlutterDartProject`.
*
* If the FlutterDartProject is not specified, the FlutterHeadlessDartRunner will attempt to locate
* the project in a default location.
*
* A newly initialized engine will not run the `FlutterDartProject` until either
* `-runWithEntrypoint:` or `-runWithEntrypoint:libraryURI` is called.
*
* @param labelPrefix The label prefix used to identify threads for this instance. Should
* be unique across FlutterEngine instances
* @param projectOrNil The `FlutterDartProject` to run.
* @param allowHeadlessExecution Must be set to `YES`.
*/
- (instancetype)initWithName:(NSString*)labelPrefix
project:(FlutterDartProject*)projectOrNil
allowHeadlessExecution:(BOOL)allowHeadlessExecution NS_DESIGNATED_INITIALIZER;
/**
* Not recommended for use - will initialize with a default label ("io.flutter.headless")
* and the default FlutterDartProject.
*/
- (instancetype)init;
@end
#endif // FLUTTER_FLUTTERHEADLESSDARTRUNNER_H_
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_FLUTTERMACROS_H_
#define FLUTTER_FLUTTERMACROS_H_
#if defined(FLUTTER_FRAMEWORK)
#define FLUTTER_EXPORT __attribute__((visibility("default")))
#else // defined(FLUTTER_SDK)
#define FLUTTER_EXPORT
#endif // defined(FLUTTER_SDK)
#ifndef NS_ASSUME_NONNULL_BEGIN
#define NS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
#define NS_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")
#endif // defined(NS_ASSUME_NONNULL_BEGIN)
/**
* Indicates that the API has been deprecated for the specified reason. Code
* that uses the deprecated API will continue to work as before. However, the
* API will soon become unavailable and users are encouraged to immediately take
* the appropriate action mentioned in the deprecation message and the BREAKING
* CHANGES section present in the Flutter.h umbrella header.
*/
#define FLUTTER_DEPRECATED(msg) __attribute__((__deprecated__(msg)))
/**
* Indicates that the previously deprecated API is now unavailable. Code that
* uses the API will not work and the declaration of the API is only a stub
* meant to display the given message detailing the actions for the user to take
* immediately.
*/
#define FLUTTER_UNAVAILABLE(msg) __attribute__((__unavailable__(msg)))
#endif // FLUTTER_FLUTTERMACROS_H_
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_FLUTTERPLATFORMVIEWS_H_
#define FLUTTER_FLUTTERPLATFORMVIEWS_H_
#import <UIKit/UIKit.h>
#import "FlutterCodecs.h"
#import "FlutterMacros.h"
NS_ASSUME_NONNULL_BEGIN
/**
* Wraps a `UIView` for embedding in the Flutter hierarchy
*/
@protocol FlutterPlatformView <NSObject>
/**
* Returns a reference to the `UIView` that is wrapped by this `FlutterPlatformView`.
*/
- (UIView*)view;
@end
FLUTTER_EXPORT
@protocol FlutterPlatformViewFactory <NSObject>
/**
* Create a `FlutterPlatformView`.
*
* Implemented by iOS code that expose a `UIView` for embedding in a Flutter app.
*
* The implementation of this method should create a new `UIView` and return it.
*
* @param frame The rectangle for the newly created `UIView` measued in points.
* @param viewId A unique identifier for this `UIView`.
* @param args Parameters for creating the `UIView` sent from the Dart side of the Flutter app.
* If `createArgsCodec` is not implemented, or if no creation arguments were sent from the Dart
* code, this will be null. Otherwise this will be the value sent from the Dart code as decoded by
* `createArgsCodec`.
*/
- (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
viewIdentifier:(int64_t)viewId
arguments:(id _Nullable)args;
/**
* Returns the `FlutterMessageCodec` for decoding the args parameter of `createWithFrame`.
*
* Only needs to be implemented if `createWithFrame` needs an arguments parameter.
*/
@optional
- (NSObject<FlutterMessageCodec>*)createArgsCodec;
@end
NS_ASSUME_NONNULL_END
#endif // FLUTTER_FLUTTERPLATFORMVIEWS_H_
This diff is collapsed.
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_FLUTTERPLUGINAPPLIFECYCLEDELEGATE_H_
#define FLUTTER_FLUTTERPLUGINAPPLIFECYCLEDELEGATE_H_
#include "FlutterPlugin.h"
NS_ASSUME_NONNULL_BEGIN
/**
* Propagates `UIAppDelegate` callbacks to registered plugins.
*/
FLUTTER_EXPORT
@interface FlutterPluginAppLifeCycleDelegate : NSObject
/**
* Registers `delegate` to receive life cycle callbacks via this FlutterPluginAppLifecycleDelegate
* as long as it is alive.
*
* `delegate` will only referenced weakly.
*/
- (void)addDelegate:(NSObject<FlutterPlugin>*)delegate;
/**
* Calls all plugins registered for `UIApplicationDelegate` callbacks.
*
* @return `NO` if any plugin vetoes application launch.
*/
- (BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions;
/**
* Calls all plugins registered for `UIApplicationDelegate` callbacks.
*
* @return `NO` if any plugin vetoes application launch.
*/
- (BOOL)application:(UIApplication*)application
willFinishLaunchingWithOptions:(NSDictionary*)launchOptions;
/**
* Calls all plugins registered for `UIApplicationDelegate` callbacks.
*/
- (void)applicationDidBecomeActive:(UIApplication*)application;
/**
* Calls all plugins registered for `UIApplicationDelegate` callbacks.
*/
- (void)applicationWillResignActive:(UIApplication*)application;
/**
* Calls all plugins registered for `UIApplicationDelegate` callbacks.
*/
- (void)applicationDidEnterBackground:(UIApplication*)application;
/**
* Calls all plugins registered for `UIApplicationDelegate` callbacks.
*/
- (void)applicationWillEnterForeground:(UIApplication*)application;
/**
* Calls all plugins registered for `UIApplicationDelegate` callbacks.
*/
- (void)applicationWillTerminate:(UIApplication*)application;
/**
* Called if this plugin has been registered for `UIApplicationDelegate` callbacks.
*/
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- (void)application:(UIApplication*)application
didRegisterUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings;
#pragma GCC diagnostic pop
/**
* Calls all plugins registered for `UIApplicationDelegate` callbacks.
*/
- (void)application:(UIApplication*)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken;
/**
* Calls all plugins registered for `UIApplicationDelegate` callbacks.
*/
- (void)application:(UIApplication*)application
didReceiveRemoteNotification:(NSDictionary*)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;
/**
* Calls all plugins registered for `UIApplicationDelegate` callbacks.
*/
- (void)application:(UIApplication*)application
didReceiveLocalNotification:(UILocalNotification*)notification;
/**
* Calls all plugins registered for `UNUserNotificationCenterDelegate` callbacks.
*/
- (void)userNotificationCenter:(UNUserNotificationCenter*)center
willPresentNotification:(UNNotification*)notification
withCompletionHandler:
(void (^)(UNNotificationPresentationOptions options))completionHandler
API_AVAILABLE(ios(10));
/**
* Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until
* some plugin handles the request.
*
* @return `YES` if any plugin handles the request.
*/
- (BOOL)application:(UIApplication*)application
openURL:(NSURL*)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id>*)options;
/**
* Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until
* some plugin handles the request.
*
* @return `YES` if any plugin handles the request.
*/
- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url;
/**
* Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until
* some plugin handles the request.
*
* @return `YES` if any plugin handles the request.
*/
- (BOOL)application:(UIApplication*)application
openURL:(NSURL*)url
sourceApplication:(NSString*)sourceApplication
annotation:(id)annotation;
/**
* Calls all plugins registered for `UIApplicationDelegate` callbacks.
*/
- (void)application:(UIApplication*)application
performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem
completionHandler:(void (^)(BOOL succeeded))completionHandler
API_AVAILABLE(ios(9.0));
/**
* Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until
* some plugin handles the request.
*
* @return `YES` if any plugin handles the request.
*/
- (BOOL)application:(UIApplication*)application
handleEventsForBackgroundURLSession:(nonnull NSString*)identifier
completionHandler:(nonnull void (^)(void))completionHandler;
/**
* Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until
* some plugin handles the request.
*
* @returns `YES` if any plugin handles the request.
*/
- (BOOL)application:(UIApplication*)application
performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;
/**
* Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until
* some plugin handles the request.
*
* @return `YES` if any plugin handles the request.
*/
- (BOOL)application:(UIApplication*)application
continueUserActivity:(NSUserActivity*)userActivity
restorationHandler:(void (^)(NSArray*))restorationHandler;
@end
NS_ASSUME_NONNULL_END
#endif // FLUTTER_FLUTTERPLUGINAPPLIFECYCLEDELEGATE_H_
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_FLUTTERTEXTURE_H_
#define FLUTTER_FLUTTERTEXTURE_H_
#import <CoreMedia/CoreMedia.h>
#import <Foundation/Foundation.h>
#include "FlutterMacros.h"
NS_ASSUME_NONNULL_BEGIN
FLUTTER_EXPORT
@protocol FlutterTexture <NSObject>
- (CVPixelBufferRef _Nullable)copyPixelBuffer;
@end
FLUTTER_EXPORT
@protocol FlutterTextureRegistry <NSObject>
- (int64_t)registerTexture:(NSObject<FlutterTexture>*)texture;
- (void)textureFrameAvailable:(int64_t)textureId;
- (void)unregisterTexture:(int64_t)textureId;
@end
NS_ASSUME_NONNULL_END
#endif // FLUTTER_FLUTTERTEXTURE_H_
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_FLUTTERVIEWCONTROLLER_H_
#define FLUTTER_FLUTTERVIEWCONTROLLER_H_
#import <UIKit/UIKit.h>
#include <sys/cdefs.h>
#include "FlutterBinaryMessenger.h"
#include "FlutterDartProject.h"
#include "FlutterEngine.h"
#include "FlutterMacros.h"
#include "FlutterPlugin.h"
#include "FlutterTexture.h"
@class FlutterEngine;
/**
* The name used for semantic update nofications via `NSNotificationCenter`.
*
* The object passed as the sender is the `FlutterViewController` associated
* with the update.
*/
FLUTTER_EXPORT
extern NSNotificationName const FlutterSemanticsUpdateNotification;
/**
* A `UIViewController` implementation for Flutter views.
*
* Dart execution, channel communication, texture registration, and plugin registration
* are all handled by `FlutterEngine`. Calls on this class to those members all proxy
* through to the `FlutterEngine` attached FlutterViewController.
*
* A FlutterViewController can be initialized either with an already-running `FlutterEngine`,
* or it can be initialized with a `FlutterDartProject` that will be used to spin up
* a new `FlutterEngine`. Developers looking to present and hide FlutterViewControllers
* in native iOS applications will usually want to maintain the `FlutterEngine` instance
* so as not to lose Dart-related state and asynchronous tasks when navigating back and
* forth between a FlutterViewController and other `UIViewController`s.
*/
FLUTTER_EXPORT
@interface FlutterViewController
: UIViewController <FlutterBinaryMessenger, FlutterTextureRegistry, FlutterPluginRegistry>
/**
* Initializes this FlutterViewController with the specified `FlutterEngine`.
*
* The initialized viewcontroller will attach itself to the engine as part of this process.
*
* @param engine The `FlutterEngine` instance to attach to.
* @param nibNameOrNil The NIB name to initialize this UIViewController with.
* @param nibBundleOrNil The NIB bundle.
*/
- (instancetype)initWithEngine:(FlutterEngine*)engine
nibName:(NSString*)nibNameOrNil
bundle:(NSBundle*)nibBundleOrNil NS_DESIGNATED_INITIALIZER;
/**
* Initializes a new FlutterViewController and `FlutterEngine` with the specified
* `FlutterDartProject`.
*
* @param projectOrNil The `FlutterDartProject` to initialize the `FlutterEngine` with.
* @param nibNameOrNil The NIB name to initialize this UIViewController with.
* @param nibBundleOrNil The NIB bundle.
*/
- (instancetype)initWithProject:(FlutterDartProject*)projectOrNil
nibName:(NSString*)nibNameOrNil
bundle:(NSBundle*)nibBundleOrNil NS_DESIGNATED_INITIALIZER;
- (void)handleStatusBarTouches:(UIEvent*)event;
/**
* Registers a callback that will be invoked when the Flutter view has been rendered.
* The callback will be fired only once.
*
* Replaces an existing callback. Use a `nil` callback to unregister the existing one.
*/
- (void)setFlutterViewDidRenderCallback:(void (^)(void))callback;
/**
* Returns the file name for the given asset.
* The returned file name can be used to access the asset in the application's
* main bundle.
*
* @param asset The name of the asset. The name can be hierarchical.
* @return The file name to be used for lookup in the main bundle.
*/
- (NSString*)lookupKeyForAsset:(NSString*)asset;
/**
* Returns the file name for the given asset which originates from the specified
* package.
* The returned file name can be used to access the asset in the application's
* main bundle.
*
* @param asset The name of the asset. The name can be hierarchical.
* @param package The name of the package from which the asset originates.
* @return The file name to be used for lookup in the main bundle.
*/
- (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package;
/**
* Sets the first route that the Flutter app shows. The default is "/".
* This method will guarnatee that the initial route is delivered, even if the
* Flutter window hasn't been created yet when called. It cannot be used to update
* the current route being shown in a visible FlutterViewController (see pushRoute
* and popRoute).
*
* @param route The name of the first route to show.
*/
- (void)setInitialRoute:(NSString*)route;
/**
* Instructs the Flutter Navigator (if any) to go back.
*/
- (void)popRoute;
/**
* Instructs the Flutter Navigator (if any) to push a route on to the navigation
* stack. The setInitialRoute method should be prefered if this is called before the
* FlutterViewController has come into view.
*
* @param route The name of the route to push to the navigation stack.
*/
- (void)pushRoute:(NSString*)route;
/**
* The `FlutterPluginRegistry` used by this FlutterViewController.
*/
- (id<FlutterPluginRegistry>)pluginRegistry;
/**
* Specifies the view to use as a splash screen. Flutter's rendering is asynchronous, so the first
* frame rendered by the Flutter application might not immediately appear when theFlutter view is
* initially placed in the view hierarchy. The splash screen view will be used as
* a replacement until the first frame is rendered.
*
* The view used should be appropriate for multiple sizes; an autoresizing mask to
* have a flexible width and height will be applied automatically.
*/
@property(strong, nonatomic) UIView* splashScreenView;
/**
* Attempts to set the `splashScreenView` property from the `UILaunchStoryboardName` from the
* main bundle's `Info.plist` file. This method will not change the value of `splashScreenView`
* if it cannot find a default one from a storyboard or nib.
*
* @return `YES` if successful, `NO` otherwise.
*/
- (BOOL)loadDefaultSplashScreenView;
/**
* Controls whether the created view will be opaque or not.
*
* Default is `YES`. Note that setting this to `NO` may negatively impact performance
* when using hardware acceleration, and toggling this will trigger a re-layout of the
* view.
*/
@property(nonatomic, getter=isViewOpaque) BOOL viewOpaque;
/**
* The `FlutterEngine` instance for this view controller.
*/
@property(weak, nonatomic, readonly) FlutterEngine* engine;
@end
#endif // FLUTTER_FLUTTERVIEWCONTROLLER_H_
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>Flutter</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Flutter</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>8.0</string>
</dict>
</plist>
framework module Flutter {
umbrella header "Flutter.h"
export *
module * { export * }
}
#
# NOTE: This podspec is NOT to be published. It is only used as a local source!
#
Pod::Spec.new do |s|
s.name = 'Flutter'
s.version = '1.0.0'
s.summary = 'High-performance, high-fidelity mobile apps.'
s.description = <<-DESC
Flutter provides an easy and productive way to build and deploy high-performance mobile apps for Android and iOS.
DESC
s.homepage = 'https://flutter.io'
s.license = { :type => 'MIT' }
s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
s.ios.deployment_target = '7.0'
s.vendored_frameworks = 'Flutter.framework'
end
def parse_KV_file(file, separator='=')
file_abs_path = File.expand_path(file)
if !File.exists? file_abs_path
return [];
end
pods_array = []
skip_line_start_symbols = ["#", "/"]
File.foreach(file_abs_path) { |line|
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
plugin = line.split(pattern=separator)
if plugin.length == 2
podname = plugin[0].strip()
path = plugin[1].strip()
podpath = File.expand_path("#{path}", file_abs_path)
pods_array.push({:name => podname, :path => podpath});
else
puts "Invalid plugin specification: #{line}"
end
}
return pods_array
end
def flutter_root(f)
generated_xcode_build_settings = parse_KV_file(File.join(f, File.join('.ios', 'Flutter', 'Generated.xcconfig')))
if generated_xcode_build_settings.empty?
puts "Generated.xcconfig must exist. Make sure `flutter packages get` is executed in #{f}."
exit
end
generated_xcode_build_settings.map { |p|
if p[:name] == 'FLUTTER_ROOT'
return p[:path]
end
}
end
# If this wasn't specified, assume it's two levels up from the directory of this script.
flutter_application_path ||= File.join(__dir__, '..', '..')
framework_dir = File.join(flutter_application_path, '.ios', 'Flutter')
engine_dir = File.join(framework_dir, 'engine')
if !File.exist?(engine_dir)
# Copy the debug engine to have something to link against if the xcode backend script has not run yet.
debug_framework_dir = File.join(flutter_root(flutter_application_path), 'bin', 'cache', 'artifacts', 'engine', 'ios')
FileUtils.mkdir_p(engine_dir)
FileUtils.cp_r(File.join(debug_framework_dir, 'Flutter.framework'), engine_dir)
FileUtils.cp(File.join(debug_framework_dir, 'Flutter.podspec'), engine_dir)
end
pod 'Flutter', :path => engine_dir
pod 'FlutterPluginRegistrant', :path => File.join(framework_dir, 'FlutterPluginRegistrant')
symlinks_dir = File.join(framework_dir, '.symlinks')
FileUtils.mkdir_p(symlinks_dir)
plugin_pods = parse_KV_file(File.join(flutter_application_path, '.flutter-plugins'))
plugin_pods.map { |r|
symlink = File.join(symlinks_dir, r[:name])
FileUtils.rm_f(symlink)
File.symlink(r[:path], symlink)
pod r[:name], :path => File.join(symlink, 'ios')
}
# Ensure that ENABLE_BITCODE is set to NO, add a #include to Generated.xcconfig, and
# add a run script to the Build Phases.
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
next if config.base_configuration_reference == nil
xcconfig_path = config.base_configuration_reference.real_path
File.open(xcconfig_path, 'a+') do |file|
file.puts "#include \"#{File.realpath(File.join(framework_dir, 'Generated.xcconfig'))}\""
end
end
end
end
platform :ios, '8.0'
#open source
source 'https://github.com/CocoaPods/Specs.git'
#our company
source 'git@git.wanmeizhensuo.com:gengmeiios/GMSpecs.git'
target 'Runner' do
pod 'TMCache'
pod 'Masonry'
pod 'SDWebImage'
pod 'GMCache'
pod 'GMKit'
pod 'GMPhobos'
flutter_application_path = '../'
eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)
end
PODS:
- Flutter (1.0.0)
- flutter_boost (0.0.1):
- Flutter
- xservice_kit
- FlutterPluginRegistrant (0.0.1):
- Flutter
- flutter_boost
- native_flutter_transfer_plugin
- xservice_kit
- GMCache (0.2.3):
- TMCache (= 2.1.0)
- GMKit (1.1.3):
- GMKit/Category (= 1.1.3)
- GMKit/Color (= 1.1.3)
- GMKit/Constant (= 1.1.3)
- GMKit/FDFullscreenPopGesture (= 1.1.3)
- GMKit/Kit (= 1.1.3)
- GMKit/Protocol (= 1.1.3)
- Masonry (= 1.1.0)
- SDWebImage (= 3.7.6)
- GMKit/Category (1.1.3):
- GMKit/Color (= 1.1.3)
- GMKit/Constant (= 1.1.3)
- GMKit/Protocol (= 1.1.3)
- Masonry (= 1.1.0)
- SDWebImage (= 3.7.6)
- GMKit/Color (1.1.3):
- Masonry (= 1.1.0)
- SDWebImage (= 3.7.6)
- GMKit/Constant (1.1.3):
- Masonry (= 1.1.0)
- SDWebImage (= 3.7.6)
- GMKit/FDFullscreenPopGesture (1.1.3):
- Masonry (= 1.1.0)
- SDWebImage (= 3.7.6)
- GMKit/Kit (1.1.3):
- GMKit/Category (= 1.1.3)
- GMKit/Color (= 1.1.3)
- GMKit/Constant (= 1.1.3)
- GMKit/Protocol (= 1.1.3)
- Masonry (= 1.1.0)
- SDWebImage (= 3.7.6)
- GMKit/Protocol (1.1.3):
- Masonry (= 1.1.0)
- SDWebImage (= 3.7.6)
- GMPhobos (1.2.2):
- GMCache (= 0.2.3)
- GMKit
- Masonry (1.1.0)
- native_flutter_transfer_plugin (0.0.1):
- Flutter
- GMCache
- GMKit (= 1.1.3)
- GMPhobos (= 1.2.2)
- Masonry
- SDWebImage
- TMCache
- SDWebImage (3.7.6):
- SDWebImage/Core (= 3.7.6)
- SDWebImage/Core (3.7.6)
- TMCache (2.1.0)
- xservice_kit (0.0.1):
- Flutter
DEPENDENCIES:
- Flutter (from `../.ios/Flutter/engine`)
- flutter_boost (from `../.ios/Flutter/.symlinks/flutter_boost/ios`)
- FlutterPluginRegistrant (from `../.ios/Flutter/FlutterPluginRegistrant`)
- GMCache
- GMKit
- GMPhobos
- Masonry
- native_flutter_transfer_plugin (from `../.ios/Flutter/.symlinks/native_flutter_transfer_plugin/ios`)
- SDWebImage
- TMCache
- xservice_kit (from `../.ios/Flutter/.symlinks/xservice_kit/ios`)
SPEC REPOS:
"git@git.wanmeizhensuo.com:gengmeiios/GMSpecs.git":
- GMCache
- GMKit
- GMPhobos
https://github.com/cocoapods/specs.git:
- Masonry
- SDWebImage
- TMCache
EXTERNAL SOURCES:
Flutter:
:path: "../.ios/Flutter/engine"
flutter_boost:
:path: "../.ios/Flutter/.symlinks/flutter_boost/ios"
FlutterPluginRegistrant:
:path: "../.ios/Flutter/FlutterPluginRegistrant"
native_flutter_transfer_plugin:
:path: "../.ios/Flutter/.symlinks/native_flutter_transfer_plugin/ios"
xservice_kit:
:path: "../.ios/Flutter/.symlinks/xservice_kit/ios"
SPEC CHECKSUMS:
Flutter: 58dd7d1b27887414a370fcccb9e645c08ffd7a6a
flutter_boost: 0e85ea37c74ed39ee7b91a35612afa1605557484
FlutterPluginRegistrant: bd1540f14a5d82de17e722f30647919e115a4479
GMCache: 09a3029c96fe130e3a21faef70b3d9d2ce92d639
GMKit: 35f788243cceeddf3e13c5226b3ea0b5e08e2117
GMPhobos: 1ae96f00a847dde2ce813d5e232b47760677fe62
Masonry: 678fab65091a9290e40e2832a55e7ab731aad201
native_flutter_transfer_plugin: b036946c34e2b1f80c39494141a4583ab133d81a
SDWebImage: c325cf02c30337336b95beff20a13df489ec0ec9
TMCache: 95ebcc9b3c7e90fb5fd8fc3036cba3aa781c9bed
xservice_kit: a2f1b35addc126fce8687aeb183ab0c1ada5b7f3
PODFILE CHECKSUM: 67a68a060c35a09e6148f9b22d60bf6929b5904e
COCOAPODS: 1.7.0
//
// GMCache.h
// Gengmei
//
// Created by Thierry on 1/5/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <TMCache/TMCache.h>
@interface GMCache : NSObject
#pragma mark - 异步磁盘读写操作
/*** @brief 由对应的键获取对应的缓存数据*/
+ (void)storeObjectAtDiskWithkey:(NSString *)key
object:(id <NSCoding>)object
block:(TMDiskCacheObjectBlock)block;
/*** @brief 给特定的键,标记缓存数据并缓存*/
+ (void)fetchObjectAtDiskWithkey:(NSString *)key
block:(TMDiskCacheObjectBlock)block;
/*** @brief 删除特定的键,对应的缓存数据*/
+ (void)removeObjectAtDiskWithkey:(NSString *)key
block:(TMDiskCacheObjectBlock)block;
/*** @brief 清空所有的缓存数据*/
+ (void)removeAllObjectsAtDiskWithBlock:(TMDiskCacheBlock)block;
#pragma mark - 同步磁盘读写操作
/*** @brief 由对应的键获取对应的缓存数据*/
+ (void)storeObjectAtDiskWithkey:(NSString *)key
object:(id <NSCoding>)object;
/*** @brief 给特定的键,标记缓存数据并缓存*/
+ (id)fetchObjectAtDiskWithkey:(NSString *)key;
/*** @brief 删除特定的键,对应的缓存数据*/
+ (void)removeObjectAtDiskWithkey:(NSString *)key;
/*** @brief 清空所有的缓存数据*/
+ (void)removeAllObjectsAtDisk;
#pragma mark - 异步内存读写操作
/*** @brief 由对应的键获取对应的缓存数据*/
+ (void)storeObjectAtMemoryWithkey:(NSString *)key
object:(id <NSCoding>)object
block:(TMMemoryCacheObjectBlock)block;
/*** @brief 给特定的键,标记缓存数据并缓存*/
+ (void)fetchObjectAtMemoryWithkey:(NSString *)key
block:(TMMemoryCacheObjectBlock)block;
/*** @brief 删除特定的键,对应的缓存数据*/
+ (void)removeObjectAtMemoryWithkey:(NSString *)key
block:(TMMemoryCacheObjectBlock)block;
/*** @brief 清空所有的缓存数据*/
+ (void)removeAllObjectsAtMemoryWithBlock:(TMMemoryCacheBlock)block;
#pragma mark - 同步内存读写操作
/*** @brief 由对应的键获取对应的缓存数据*/
+ (void)storeObjectAtMemoryWithkey:(NSString *)key
object:(id)object;
/*** @brief 给特定的键,标记缓存数据并缓存*/
+ (id)fetchObjectAtMemoryWithkey:(NSString *)key;
/*** @brief 删除特定的键,对应的缓存数据*/
+ (void)removeObjectAtMemoryWithkey:(NSString *)key;
/*** @brief 清空所有的缓存数据*/
+ (void)removeAllObjectsAtMemory;
#pragma mark - 这里将数据缓存到Ducument目录下。异步
+ (void)storeObjectAtDocumentPathWithkey:(NSString *)key
object:(id <NSCoding>)object
block:(TMDiskCacheObjectBlock)block;
+ (void)fetchObjectAtDocumentPathWithkey:(NSString *)key
block:(TMDiskCacheObjectBlock)block;
+ (void)removeObjectAtDocumentPathWithkey:(NSString *)key
block:(TMDiskCacheObjectBlock)block;
+ (void)removeAllObjectsAtDocumentPathWithBlock:(TMDiskCacheBlock)block;
#pragma mark - 这里将数据缓存到Ducument目录下。同步内存读写操作
+ (void)storeObjectAtDocumentPathWithkey:(NSString *)key
object:(id <NSCoding>)object;
+ (id)fetchObjectAtDocumentPathWithkey:(NSString *)key;
+ (void)removeObjectAtDocumentPathWithkey:(NSString *)key;
+ (void)removeAllObjectsAtDocumentPath;
@end
//
// GMCache.m
// Gengmei
//
// Created by Thierry on 1/5/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import "GMCache.h"
@interface WMDocumentCache : TMCache
@end
@implementation GMCache
+ (void)storeObjectAtDiskWithkey:(NSString *)key object:(id <NSCoding>)object block:(TMDiskCacheObjectBlock)block{
NSAssert([GMCache gmCache_isNonEmpty:key], @"key不能为空");
if (![GMCache gmCache_isNonEmpty:key]) {
return;
}
[[TMCache sharedCache].diskCache setObject:object forKey:key block:block];
}
+ (void)fetchObjectAtDiskWithkey:(NSString *)key block:(TMDiskCacheObjectBlock)block{
NSAssert([GMCache gmCache_isNonEmpty:key], @"key不能为空");
if (![GMCache gmCache_isNonEmpty:key]) {
return;
}
[[TMCache sharedCache].diskCache objectForKey:key block:block];
}
+ (void)removeObjectAtDiskWithkey:(NSString *)key block:(TMDiskCacheObjectBlock)block{
NSAssert([GMCache gmCache_isNonEmpty:key], @"key不能为空");
if (![GMCache gmCache_isNonEmpty:key]) {
return;
}
[[TMCache sharedCache].diskCache removeObjectForKey:key block:block];
}
+ (void)removeAllObjectsAtDiskWithBlock:(TMDiskCacheBlock)block{
[[TMCache sharedCache].diskCache removeAllObjects:block];
}
+ (void)storeObjectAtDiskWithkey:(NSString *)key object:(id <NSCoding>)object{
NSAssert([GMCache gmCache_isNonEmpty:key], @"key不能为空");
if (![GMCache gmCache_isNonEmpty:key]) {
return;
}
[[TMCache sharedCache].diskCache setObject:object forKey:key];
}
+ (id)fetchObjectAtDiskWithkey:(NSString *)key{
NSAssert([GMCache gmCache_isNonEmpty:key], @"key不能为空");
if (![GMCache gmCache_isNonEmpty:key]) {
return nil;
}
return [[TMCache sharedCache].diskCache objectForKey:key];
}
+ (void)removeObjectAtDiskWithkey:(NSString *)key{
NSAssert([GMCache gmCache_isNonEmpty:key], @"key不能为空");
if (![GMCache gmCache_isNonEmpty:key]) {
return;
}
[[TMCache sharedCache].diskCache removeObjectForKey:key];
}
+ (void)removeAllObjectsAtDisk{
[[TMCache sharedCache].diskCache removeAllObjects];
}
+ (void)storeObjectAtMemoryWithkey:(NSString *)key object:(id <NSCoding>)object block:(TMMemoryCacheObjectBlock)block{
NSAssert([GMCache gmCache_isNonEmpty:key], @"key不能为空");
if (![GMCache gmCache_isNonEmpty:key]) {
return;
}
[[TMCache sharedCache].memoryCache setObject:object forKey:key block:block];
}
+ (void)fetchObjectAtMemoryWithkey:(NSString *)key block:(TMMemoryCacheObjectBlock)block{
NSAssert([GMCache gmCache_isNonEmpty:key], @"key不能为空");
if (![GMCache gmCache_isNonEmpty:key]) {
return;
}
[[TMCache sharedCache].memoryCache objectForKey:key block:block];
}
+ (void)removeObjectAtMemoryWithkey:(NSString *)key block:(TMMemoryCacheObjectBlock)block{
NSAssert([GMCache gmCache_isNonEmpty:key], @"key不能为空");
if (![GMCache gmCache_isNonEmpty:key]) {
return;
}
[[TMCache sharedCache].memoryCache removeObjectForKey:key block:block];
}
+ (void)removeAllObjectsAtMemoryWithBlock:(TMMemoryCacheBlock)block{
[[TMCache sharedCache].memoryCache removeAllObjects:block];
}
+ (void)storeObjectAtMemoryWithkey:(NSString *)key object:(id)object{
NSAssert([GMCache gmCache_isNonEmpty:key], @"key不能为空");
if (![GMCache gmCache_isNonEmpty:key]) {
return;
}
[[TMCache sharedCache].memoryCache setObject:object forKey:key];
}
+ (id)fetchObjectAtMemoryWithkey:(NSString *)key{
NSAssert([GMCache gmCache_isNonEmpty:key], @"key不能为空");
if (![GMCache gmCache_isNonEmpty:key]) {
return nil;
}
return [[TMCache sharedCache].memoryCache objectForKey:key];
}
+ (void)removeObjectAtMemoryWithkey:(NSString *)key{
NSAssert([GMCache gmCache_isNonEmpty:key], @"key不能为空");
if (![GMCache gmCache_isNonEmpty:key]) {
return;
}
[[TMCache sharedCache].memoryCache removeObjectForKey:key];
}
+ (void)removeAllObjectsAtMemory{
[[TMCache sharedCache].memoryCache removeAllObjects];
}
+ (void)storeObjectAtDocumentPathWithkey:(NSString *)key
object:(id <NSCoding>)object
block:(TMDiskCacheObjectBlock)block{
NSAssert([GMCache gmCache_isNonEmpty:key], @"key不能为空");
if (![GMCache gmCache_isNonEmpty:key]) {
return;
}
[[WMDocumentCache sharedCache].diskCache setObject:object forKey:key block:block];
}
+ (void)fetchObjectAtDocumentPathWithkey:(NSString *)key
block:(TMDiskCacheObjectBlock)block{
NSAssert([GMCache gmCache_isNonEmpty:key], @"key不能为空");
if (![GMCache gmCache_isNonEmpty:key]) {
return;
}
[[WMDocumentCache sharedCache].diskCache objectForKey:key block:block];
}
+ (void)removeObjectAtDocumentPathWithkey:(NSString *)key
block:(TMDiskCacheObjectBlock)block{
NSAssert([GMCache gmCache_isNonEmpty:key], @"key不能为空");
if (![GMCache gmCache_isNonEmpty:key]) {
return;
}
[[WMDocumentCache sharedCache].diskCache removeObjectForKey:key block:block];
}
+ (void)removeAllObjectsAtDocumentPathWithBlock:(TMDiskCacheBlock)block{
[[WMDocumentCache sharedCache].diskCache removeAllObjects:block];
}
+ (void)storeObjectAtDocumentPathWithkey:(NSString *)key
object:(id <NSCoding>)object{
NSAssert([GMCache gmCache_isNonEmpty:key], @"key不能为空");
if (![GMCache gmCache_isNonEmpty:key]) {
return;
}
[[WMDocumentCache sharedCache].diskCache setObject:object forKey:key];
}
+ (id)fetchObjectAtDocumentPathWithkey:(NSString *)key{
NSAssert([GMCache gmCache_isNonEmpty:key], @"key不能为空");
if (![GMCache gmCache_isNonEmpty:key]) {
return nil;
}
return [[WMDocumentCache sharedCache].diskCache objectForKey:key];
}
+ (void)removeObjectAtDocumentPathWithkey:(NSString *)key{
NSAssert([GMCache gmCache_isNonEmpty:key], @"key不能为空");
if (![GMCache gmCache_isNonEmpty:key]) {
return;
}
[[WMDocumentCache sharedCache].diskCache removeObjectForKey:key];
}
+ (void)removeAllObjectsAtDocumentPath{
[[WMDocumentCache sharedCache].diskCache removeAllObjects];
}
+ (BOOL)gmCache_isNonEmpty:(NSString *)key {
NSMutableCharacterSet *emptyStringSet = [[NSMutableCharacterSet alloc] init];
[emptyStringSet formUnionWithCharacterSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
[emptyStringSet formUnionWithCharacterSet: [NSCharacterSet characterSetWithCharactersInString: @" "]];
if ([key length] == 0) {
return NO;
}
NSString* str = [key stringByTrimmingCharactersInSet:emptyStringSet];
return [str length] > 0;
}
@end
NSString * const WMCacheSharedName = @"WMCacheShared";
@implementation WMDocumentCache
+ (instancetype)sharedCache{
static id cache;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
cache = [[self alloc] initWithName:WMCacheSharedName rootPath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]];
});
return cache;
}
@end
Copyright (c) 2016 wangyang <wangyang@wanmeizhensuo.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
# GMCache
[![CI Status](http://img.shields.io/travis/wangyang/GMCache.svg?style=flat)](https://travis-ci.org/wangyang/GMCache)
[![Version](https://img.shields.io/cocoapods/v/GMCache.svg?style=flat)](http://cocoapods.org/pods/GMCache)
[![License](https://img.shields.io/cocoapods/l/GMCache.svg?style=flat)](http://cocoapods.org/pods/GMCache)
[![Platform](https://img.shields.io/cocoapods/p/GMCache.svg?style=flat)](http://cocoapods.org/pods/GMCache)
## Usage
To run the example project, clone the repo, and run `pod install` from the Example directory first.
## Requirements
## Installation
GMCache is available through [CocoaPods](http://cocoapods.org). To install
it, simply add the following line to your Podfile:
```ruby
pod "GMCache"
```
## Author
wangyang, wangyang@wanmeizhensuo.com
## License
GMCache is available under the MIT license. See the LICENSE file for more info.
Copyright (c) 2016 北京更美互动信息科技有限公司
仅限北京更美互动信息科技有限公司内部使用
//
// UIDevice+Reso.m
// Simple UIDevice Category for handling different iOSs hardware resolutions
//
// Created by Alejandro Luengo on 29/09/14.
// (c) 2014 Intelygenz
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSUInteger, UIDeviceResolution) {
UnknowDevice = 0, //未知设备
iPhone35Inches = 1, //3.5英寸、iphone4s
iPhone40Inches = 2, //4英寸iphone5、iphone5c、iphone5s
iPhone47Inches = 3, //4.7英寸iphone6、iphone7、iphone8
iPhone55Inches = 4, //5.5英寸iphone6 plus、iphone7 plus、iphone8 plus
iPhone58Inches = 5, //5.5英寸iphoneX
iPhoneXRInches = 6, //iphone XR
iPhoneXSMaxInches = 7 //iphone XS Max
};
typedef NS_ENUM(NSInteger, GMDeviceType) {
GMDeviceTypeUnknow = 0,
GMDeviceTypeSimulator,
GMDeviceTypeIPad,
GMDeviceTypeIPod,
GMDeviceTypeIPhone4,
GMDeviceTypeIPhone4S,
GMDeviceTypeIPhone5,
GMDeviceTypeIPhone5S,
GMDeviceTypeIPhone5C,
GMDeviceTypeIPhone6,
GMDeviceTypeIPhone6P,
GMDeviceTypeIPhone6S,
GMDeviceTypeIPhone6SP,
GMDeviceTypeIPhone7,
GMDeviceTypeIPhone7P,
GMDeviceTypeIPhone8,
GMDeviceTypeIPhone8P,
GMDeviceTypeIPhoneX,
GMDeviceTypeIPhoneXR,
GMDeviceTypeIPhoneXS,
GMDeviceTypeIPhoneXSMax,
};
typedef NS_ENUM(NSUInteger, GMDeviceAspectRatioType) {
GMDeviceAspectRatioTypeNarrow, //iPad、iphone4s、iphone5
GMDeviceAspectRatioTypeNormal, // Normal
GMDeviceAspectRatioTypeWide, // Plus、Max
};
@interface UIDevice (Resolutions)
/**
* @author licong, 16-12-29 17:12:54
*
* 判断设备的类型(eg:当前设备是5还是6s)
*
* @return 返回设备类型
*
* @since 5.8
*/
+ (UIDeviceResolution)resolutionType __deprecated_msg("A note to the developers using it.");
+ (GMDeviceAspectRatioType)aspectRatioType;
+ (NSString *)platform;
/**
获取设备的deviceId,如果能去到idfa,就返回idfa,否则就返回idfv
@author zhaiguojun 16-10-31 in (null)
@return deviceId
@since 6.5.0
*/
+ (NSString *)deviceId;
/**
获取设备详细类型,目前只到6s,和6s plus
@author zhaiguojun 16-09-18 in (null)
@return model
@since 6.3.0
*/
+ (NSString*)deviceVersion;
@end
//
// UIDevice+Reso.m
// Simple UIDevice Category for handling different iOSs hardware resolutions
//
// Created by Alejandro Luengo on 29/09/14.
// (c) 2014 Intelygenz
// iPhone 6 Plus 736x414 points 2208x1242 pixels 3x scale
// iPhone 6 667x375 points 1334x750 pixels 2x scale
// iPhone 5 568x320 points 1136x640 pixels 2x scale
// iPhone 4s 480x320 points 960x640 pixels 2x scale
// iPad 1024x768 points 1024x768 pixels 1x scale
// iPad Retina 1024x768 points 2048x1536 pixels 2x scale
#import "UIDevice+Resolutions.h"
#import "sys/utsname.h"
#import <AdSupport/AdSupport.h>
@implementation UIDevice (Resolutions)
+ (NSString *)deviceId {
NSString *idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
if (![idfa isEqualToString:@"00000000-0000-0000-0000-000000000000"]) {
return idfa;
}
return idfv;
}
+ (UIDeviceResolution)resolutionType
{
UIScreenMode *mode = [UIScreen mainScreen].preferredMode;
if (mode.size.height == 960) {
return iPhone35Inches;
}
else if (mode.size.height == 1136) {
return iPhone40Inches;
}
else if (mode.size.height == 1334) {
return iPhone47Inches;
}
else if (mode.size.height == 2208) {
return iPhone55Inches;
}
else if (mode.size.height == 2436) {
return iPhone58Inches;
}
else if (mode.size.height == 1792) {
return iPhoneXRInches;
}
else if (mode.size.height == 2688) {
return iPhoneXSMaxInches;
}
else
return UnknowDevice;
}
+ (GMDeviceAspectRatioType)aspectRatioType {
UIDevice *device = [UIDevice currentDevice];
if ([device.model containsString:@"iPad"])
return GMDeviceAspectRatioTypeNarrow;
NSString *deviceVersion = [self deviceVersion];
UIScreenMode *mode = [UIScreen mainScreen].preferredMode;
if ([deviceVersion containsString:@"iPhone 4"] || [deviceVersion containsString:@"iPhone 5"] || mode.size.height == 960 || mode.size.height == 1136)
return GMDeviceAspectRatioTypeNarrow;
else if ([deviceVersion containsString:@"Plus"] || [deviceVersion containsString:@"Max"])
return GMDeviceAspectRatioTypeWide;
else
return GMDeviceAspectRatioTypeNormal;
}
+ (NSString *)platform {
struct utsname systemInfo;
uname(&systemInfo);
NSString *platform = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
return platform;
}
+ (NSString*)deviceVersion{
NSString *platform = [self platform];
//iPhone
if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4";
if ([platform isEqualToString:@"iPhone3,2"]) return @"iPhone 4";
if ([platform isEqualToString:@"iPhone3,3"]) return @"iPhone 4";
if ([platform isEqualToString:@"iPhone4,1"]) return @"iPhone 4S";
if ([platform isEqualToString:@"iPhone5,1"]) return @"iPhone 5";
if ([platform isEqualToString:@"iPhone5,2"]) return @"iPhone 5";
if ([platform isEqualToString:@"iPhone5,3"]) return @"iPhone 5C";
if ([platform isEqualToString:@"iPhone5,4"]) return @"iPhone 5C";
if ([platform isEqualToString:@"iPhone6,1"]) return @"iPhone 5S";
if ([platform isEqualToString:@"iPhone6,2"]) return @"iPhone 5S";
if ([platform isEqualToString:@"iPhone7,1"]) return @"iPhone 6 Plus";
if ([platform isEqualToString:@"iPhone7,2"]) return @"iPhone 6";
if ([platform isEqualToString:@"iPhone8,1"]) return @"iPhone 6s";
if ([platform isEqualToString:@"iPhone8,2"]) return @"iPhone 6s Plus";
if ([platform isEqualToString:@"iPhone8,3"]) return @"iPhoneSE";
if ([platform isEqualToString:@"iPhone8,4"]) return @"iPhoneSE";
if ([platform isEqualToString:@"iPhone9,1"]) return @"iPhone 7";
if ([platform isEqualToString:@"iPhone9,3"]) return @"iPhone 7";
if ([platform isEqualToString:@"iPhone9,2"]) return @"iPhone 7 Plus";
if ([platform isEqualToString:@"iPhone9,4"]) return @"iPhone 7 Plus";
if ([platform isEqualToString:@"iPhone10,1"]) return @"iPhone 8";
if ([platform isEqualToString:@"iPhone10,4"]) return @"iPhone 8";
if ([platform isEqualToString:@"iPhone10,2"]) return @"iPhone 8 Plus";
if ([platform isEqualToString:@"iPhone10,5"]) return @"iPhone 8 Plus";
if ([platform isEqualToString:@"iPhone10,3"]) return @"iPhone X";
if ([platform isEqualToString:@"iPhone10,6"]) return @"iPhone X";
if ([platform isEqualToString:@"iPhone11,8"]) return @"iPhone XR";
if ([platform isEqualToString:@"iPhone11,2"]) return @"iPhone XS";
if ([platform isEqualToString:@"iPhone11,4"]) return @"iPhone XS Max";
if ([platform isEqualToString:@"iPhone11,6"]) return @"iPhone XS Max";
return @"iphone X ++";
}
@end
//
// UIImage+GM.h
// Gengmei
//
// Created by licong on 15/12/29. Rewrite by wangyang on 2016-7-4
// Copyright © 2016年 Wanmeichuangyi. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIImage (GM)
/**
* @brief 通过颜色生成图片
*
* @param color 颜色
*/
+ (UIImage *)imageWithColor:(UIColor *)color;
/**
* @author licong, 16-12-29 18:12:48
*
* 将图片调整到设定大小
*
* @param size 设定的图片大小
*
* @return 得到设定大小后的图片
*
* @since 5.8
*/
- (UIImage *)resizedImageWithSize:(CGSize)size;
/**
使用该方法的前提条件是认为这个图片为3倍图,使用该方法将返回一个适用于当前设备scale的UIImage实例。
比如一张90像素x90像素的网络下载的图片,使用该方法
- iPhone 8 Plus机型将返回一个size为(30, 30),scale=3的UIImage;
- iPhone 8 机型将返回返回一个size为(30, 30),scale=2的UIImage;
*/
- (UIImage *)resizeToDeviceScale;
/**
* @author wangyang in 2016-7-1
*
* 参考rotatedWithTransform
*/
- (UIImage *)rotatedWithAngle:(double)angle;
/**
* @author wangyang in 2016-7-1
*
* 使用这个方法旋转图片,导出的图片的imageOrientation为Up,绘制时会同时考虑待旋转图片的原 imageOrientation 与参数 transform
@note
1. 使用这个方法进行旋转,导出的图片大小可能会发生变化。比如旋转45度,那么能容下原图的bounds肯定要大一些;比如旋转90度,图片的高宽就会互换。
2. 旋转角度为0时,可以用来将图片的imageOrientation重置为Up。
* @return 新图片
*/
- (UIImage *)rotatedWithTransform:(CGAffineTransform)transform;
/**
* @author wangyang in 2016-7-4
*
* 裁剪图片
*/
- (UIImage *)imageWithCropRect:(CGRect)rect;
@end
//
// UIImage+GM.m
// Gengmei
//
// Created by licong on 15/12/29. Rewrite by wangyang on 2016-7-4
// Copyright © 2016年 Wanmeichuangyi. All rights reserved.
//
#import "UIImage+GM.h"
@implementation UIImage (GM)
#pragma mark - 从颜色生成图片
+ (UIImage *)imageWithColor:(UIColor *)color {
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
#pragma mark - 改变大小
- (UIImage *)resizedImageWithSize:(CGSize)size {
UIGraphicsBeginImageContext(size);
CGRect rect = CGRectMake(0, 0, size.width, size.height);
// CGContextDrawImage时需要额外考虑UIImage.imageOrientation,drawInRect可以自动帮我们做好这件事
[self drawInRect:rect];
// 另外,我们不需要指定使用 CGContextSetInterpolationQuality,使用默认值Hight就可以。参考http://stackoverflow.com/questions/5685884/imagequality-with-cgcontextsetinterpolationquality
UIImage *newImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImg;
}
- (UIImage *)resizeToDeviceScale {
CGSize newSize = CGSizeMake(ceilf(self.size.width / 3), ceilf(self.size.height / 3));
UIGraphicsBeginImageContextWithOptions(newSize, NO, [UIScreen mainScreen].scale);
CGRect rect = CGRectMake(0, 0, newSize.width, newSize.height);
// CGContextDrawImage时需要额外考虑UIImage.imageOrientation,drawInRect可以自动帮我们做好这件事
[self drawInRect:rect];
// 另外,我们不需要指定使用 CGContextSetInterpolationQuality,使用默认值Hight就可以。参考http://stackoverflow.com/questions/5685884/imagequality-with-cgcontextsetinterpolationquality
UIImage *newImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImg;
}
#pragma mark - 旋转
- (UIImage *)rotatedWithAngle:(double)angle
{
CGAffineTransform transform = CGAffineTransformMakeRotation(angle * M_PI / 180);
return [self rotatedWithTransform:transform];
}
- (UIImage *)rotatedWithTransform:(CGAffineTransform)transform {
// 旋转后图片的大小
CGRect rotatedRect = CGRectApplyAffineTransform(CGRectMake(0, 0, self.size.width, self.size.height), transform);
rotatedRect.origin.x = 0;
rotatedRect.origin.y = 0;
CGSize rotatedSize = rotatedRect.size;
UIGraphicsBeginImageContextWithOptions(rotatedSize, YES, self.scale);
CGContextRef bitmap = UIGraphicsGetCurrentContext();
// 将 origin 图片的移动中间, 这样我们就可以绕着中心点旋转
CGContextTranslateCTM(bitmap, rotatedSize.width / 2, rotatedSize.height / 2);
// 旋转画布布
CGContextConcatCTM(bitmap, transform);
// 再将 origin 移回来
CGContextTranslateCTM(bitmap, rotatedSize.width / -2, rotatedSize.height / -2);
// drawInRect 会考虑图片的 orientation,也会考虑当前Context的变换
[self drawInRect:rotatedRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
#pragma mark - 剪切
- (UIImage *)imageWithCropRect:(CGRect)rect
{
CGImageRef croppedImage = CGImageCreateWithImageInRect(self.CGImage, rect);
UIImage *image = [UIImage imageWithCGImage:croppedImage];
CGImageRelease(croppedImage);
return image;
}
@end
//
// UILabel+CopyExtern.h
// CopyLabel
//
// Created by XingBo on 14-4-1.
// Copyright (c) 2014年 XingBo. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UILabel (CopyExtern)
- (void)attachTapHandler;
@end
//
// UILabel+CopyExtern.m
// CopyLabel
//
// Created by XingBo on 14-4-1.
// Copyright (c) 2014年 XingBo. All rights reserved.
//
#import "UILabel+CopyExtern.h"
@implementation UILabel (CopyExtern)
-(BOOL)canBecomeFirstResponder
{
return YES;
}
// 可以响应的方法
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
return (action == @selector(copyText:));
}
//针对于响应方法的实现
-(void)copyText:(id)sender
{
UIPasteboard *pboard = [UIPasteboard generalPasteboard];
/**
fix帖子详情页 楼主发帖复制崩溃bug
因为某些富文本label只设置了attributedText,导致self.text为nil崩溃
*/
if (self.text) {
pboard.string = self.text;
}else{
pboard.string = self.attributedText.string;
}
}
//UILabel默认是不接收事件的,我们需要自己添加touch事件
-(void)attachTapHandler{
self.userInteractionEnabled = YES; //用户交互的总开关
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[self addGestureRecognizer:longPress];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIMenuControllerWillShowMenuNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIMenuControllerWillHideMenuNotification object:nil];
}
#pragma mark - notifation methods
- (void)menuShow:(NSNotification *)sender
{
if (self.isFirstResponder) {
self.backgroundColor = [UIColor grayColor];
}
}
- (void)menuHide:(NSNotification *)sender
{
self.backgroundColor = [UIColor clearColor];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
-(void)handleTap:(UIGestureRecognizer*) recognizer
{
if (recognizer.state == UIGestureRecognizerStateBegan) {
[self becomeFirstResponder];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuShow:) name:UIMenuControllerWillShowMenuNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuHide:) name:UIMenuControllerWillHideMenuNotification object:nil];
[[UIMenuController sharedMenuController] setMenuItems:nil];
UIMenuItem *copyLink = [[UIMenuItem alloc] initWithTitle:@"复制"
action:@selector(copyText:)];
[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObjects:copyLink, nil]];
[[UIMenuController sharedMenuController] setTargetRect:self.frame inView:self.superview];
[[UIMenuController sharedMenuController] setMenuVisible:YES animated: YES];
// label复制选中时的背景颜色
self.backgroundColor = [UIColor clearColor];
}
}
@end
//
// UITextView+Keyboard.h
// ZhengXing
//
// Created by Tulipa on 14-8-22.
// Copyright (c) 2014年 Wanmei Creative. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UITextView (Keyboard)
@property (nonatomic, assign) BOOL hasCloseButton;
@end
@interface UITextField (Keyboard)
@property (nonatomic, assign) BOOL hasCloseButton;
@end
//
// UITextView+Keyboard.m
// ZhengXing
//
// Created by Tulipa on 14-8-22.
// Copyright (c) 2014年 Wanmei Creative. All rights reserved.
//
#import "UITextView+Keyboard.h"
#import "UIView+Layout.h"
@implementation UITextView (Keyboard)
- (BOOL)hasCloseButton
{
return self.inputAccessoryView != nil;
}
- (void)setHasCloseButton:(BOOL)hasCloseButton
{
if (hasCloseButton)
{
UIButton *closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[closeButton setBackgroundImage:[UIImage imageNamed:@"keyboard"] forState:UIControlStateNormal];
[closeButton sizeToFit];
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, closeButton.height)];
[view addSubview:closeButton];
[view setBackgroundColor:[UIColor clearColor]];
[closeButton setRight:view.width];
[closeButton setTop:0];
[closeButton addTarget:self action:@selector(resignFirstResponder) forControlEvents:UIControlEventTouchUpInside];
self.inputAccessoryView = view;
}
else
{
self.inputAccessoryView = nil;
}
}
@end
@implementation UITextField (Keyboard)
- (BOOL)hasCloseButton
{
return self.inputAccessoryView != nil;
}
- (void)setHasCloseButton:(BOOL)hasCloseButton
{
if (hasCloseButton)
{
UIButton *closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[closeButton setBackgroundImage:[UIImage imageNamed:@"keyboard"] forState:UIControlStateNormal];
[closeButton sizeToFit];
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, closeButton.height)];
[view addSubview:closeButton];
[view setBackgroundColor:[UIColor clearColor]];
[closeButton setRight:view.width];
[closeButton setTop:0];
[closeButton addTarget:self action:@selector(resignFirstResponder) forControlEvents:UIControlEventTouchUpInside];
self.inputAccessoryView = view;
}
else
{
self.inputAccessoryView = nil;
}
}
@end
//
// UIView+Layout.h
// Gengmei
//
// Created by licong on 15/12/29.
// Copyright © 2015年 Wanmeichuangyi. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIView (Layout)
/**
* Shortcut for frame.origin.x.
*
* Sets frame.origin.x = left
*/
@property (nonatomic) CGFloat left;
/**
* Shortcut for frame.origin.y
*
* Sets frame.origin.y = top
*/
@property (nonatomic) CGFloat top;
/**
* Shortcut for frame.origin.x + frame.size.width
*
* Sets frame.origin.x = right - frame.size.width
*/
@property (nonatomic) CGFloat right;
/**
* Shortcut for frame.origin.y + frame.size.height
*
* Sets frame.origin.y = bottom - frame.size.height
*/
@property (nonatomic) CGFloat bottom;
/**
* Shortcut for frame.size.width
*
* Sets frame.size.width = width
*/
@property (nonatomic) CGFloat width;
/**
* Shortcut for frame.size.height
*
* Sets frame.size.height = height
*/
@property (nonatomic) CGFloat height;
/**
* Shortcut for center.x
*
* Sets center.x = centerX
*/
@property (nonatomic) CGFloat centerX;
/**
* Shortcut for center.y
*
* Sets center.y = centerY
*/
@property (nonatomic) CGFloat centerY;
/**
* Return the x coordinate on the screen.
*/
@property (nonatomic, readonly) CGFloat screenX;
/**
* Return the y coordinate on the screen.
*/
@property (nonatomic, readonly) CGFloat screenY;
/**
* Return the x coordinate on the screen, taking into account scroll views.
*/
@property (nonatomic, readonly) CGFloat screenViewX;
/**
* Return the y coordinate on the screen, taking into account scroll views.
*/
@property (nonatomic, readonly) CGFloat screenViewY;
/**
* Return the view frame on the screen, taking into account scroll views.
*/
@property (nonatomic, readonly) CGRect screenFrame;
/**
* Shortcut for frame.origin
*/
@property (nonatomic) CGPoint origin;
/**
* Shortcut for frame.size
*/
@property (nonatomic) CGSize size;
/**
* Return the width in portrait or the height in landscape.
*/
@property (nonatomic, readonly) CGFloat orientationWidth;
/**
* Return the height in portrait or the width in landscape.
*/
@property (nonatomic, readonly) CGFloat orientationHeight;
/**
* Finds the first descendant view (including this view) that is a member of a particular class.
*/
- (UIView*)descendantOrSelfWithClass:(Class)cls;
/**
* Finds the first ancestor view (including this view) that is a member of a particular class.
*/
- (UIView*)ancestorOrSelfWithClass:(Class)cls;
/**
* Removes all subviews.
*/
- (void)removeAllSubviews;
@end
@interface UIView (GestureAction)
/**
Attaches the given block for a single tap action to the receiver.
@param block The block to execute.
*/
- (void)setTapActionWithBlock:(void (^)(void))block;
//- (void)removeTapAction;
/**
Attaches the given block for a long press action to the receiver.
@param block The block to execute.
*/
- (void)setLongPressActionWithBlock:(void (^)(void))block;
@end
//
// UIView+Layout.m
// Gengmei
//
// Created by licong on 15/12/29.
// Copyright © 2015年 Wanmeichuangyi. All rights reserved.
//
#import "UIView+Layout.h"
#import <objc/runtime.h>
static char kDTActionHandlerTapBlockKey;
static char kDTActionHandlerTapGestureKey;
static char kDTActionHandlerLongPressBlockKey;
static char kDTActionHandlerLongPressGestureKey;
@implementation UIView (Layout)
- (CGFloat)left {
return self.frame.origin.x;
}
- (void)setLeft:(CGFloat)x {
CGRect frame = self.frame;
frame.origin.x = x;
self.frame = frame;
}
- (CGFloat)top {
return self.frame.origin.y;
}
- (void)setTop:(CGFloat)y {
CGRect frame = self.frame;
frame.origin.y = y;
self.frame = frame;
}
- (CGFloat)right {
return self.frame.origin.x + self.frame.size.width;
}
- (void)setRight:(CGFloat)right {
CGRect frame = self.frame;
frame.origin.x = right - frame.size.width;
self.frame = frame;
}
- (CGFloat)bottom {
return self.frame.origin.y + self.frame.size.height;
}
- (void)setBottom:(CGFloat)bottom {
CGRect frame = self.frame;
frame.origin.y = bottom - frame.size.height;
self.frame = frame;
}
- (CGFloat)centerX {
return self.center.x;
}
- (void)setCenterX:(CGFloat)centerX {
self.center = CGPointMake(centerX, self.center.y);
}
- (CGFloat)centerY {
return self.center.y;
}
- (void)setCenterY:(CGFloat)centerY {
self.center = CGPointMake(self.center.x, centerY);
}
- (CGFloat)width {
return self.frame.size.width;
}
- (void)setWidth:(CGFloat)width {
CGRect frame = self.frame;
frame.size.width = width;
self.frame = frame;
}
- (CGFloat)height {
return self.frame.size.height;
}
- (void)setHeight:(CGFloat)height {
CGRect frame = self.frame;
frame.size.height = height;
self.frame = frame;
}
- (CGFloat)screenX {
CGFloat x = 0.0f;
for (UIView* view = self; view; view = view.superview) {
x += view.left;
}
return x;
}
- (CGFloat)screenY {
CGFloat y = 0.0f;
for (UIView* view = self; view; view = view.superview) {
y += view.top;
}
return y;
}
- (CGFloat)screenViewX {
CGFloat x = 0.0f;
for (UIView* view = self; view; view = view.superview) {
x += view.left;
if ([view isKindOfClass:[UIScrollView class]]) {
UIScrollView* scrollView = (UIScrollView*)view;
x -= scrollView.contentOffset.x;
}
}
return x;
}
- (CGFloat)screenViewY {
CGFloat y = 0;
for (UIView* view = self; view; view = view.superview) {
y += view.top;
if ([view isKindOfClass:[UIScrollView class]]) {
UIScrollView* scrollView = (UIScrollView*)view;
y -= scrollView.contentOffset.y;
}
}
return y;
}
- (CGRect)screenFrame {
return CGRectMake(self.screenViewX, self.screenViewY, self.width, self.height);
}
- (CGPoint)origin {
return self.frame.origin;
}
- (void)setOrigin:(CGPoint)origin {
CGRect frame = self.frame;
frame.origin = origin;
self.frame = frame;
}
- (CGSize)size {
return self.frame.size;
}
- (void)setSize:(CGSize)size {
CGRect frame = self.frame;
frame.size = size;
self.frame = frame;
}
- (CGFloat)orientationWidth {
return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)
? self.height : self.width;
}
- (CGFloat)orientationHeight {
return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)
? self.width : self.height;
}
- (UIView*)descendantOrSelfWithClass:(Class)cls {
if ([self isKindOfClass:cls])
return self;
for (UIView* child in self.subviews) {
UIView* it = [child descendantOrSelfWithClass:cls];
if (it)
return it;
}
return nil;
}
- (UIView*)ancestorOrSelfWithClass:(Class)cls {
if ([self isKindOfClass:cls]) {
return self;
} else if (self.superview) {
return [self.superview ancestorOrSelfWithClass:cls];
} else {
return nil;
}
}
- (void)removeAllSubviews {
while (self.subviews.count) {
UIView* child = self.subviews.lastObject;
[child removeFromSuperview];
}
}
- (CGPoint)offsetFromView:(UIView*)otherView {
CGFloat x = 0.0f, y = 0.0f;
for (UIView* view = self; view && view != otherView; view = view.superview) {
x += view.left;
y += view.top;
}
return CGPointMake(x, y);
}
@end
@implementation UIView (GestureAction)
- (void)setTapActionWithBlock:(void (^)(void))block
{
UITapGestureRecognizer *gesture = objc_getAssociatedObject(self, &kDTActionHandlerTapGestureKey);
if (!gesture)
{
gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(__handleActionForTapGesture:)];
[self addGestureRecognizer:gesture];
objc_setAssociatedObject(self, &kDTActionHandlerTapGestureKey, gesture, OBJC_ASSOCIATION_RETAIN);
}
objc_setAssociatedObject(self, &kDTActionHandlerTapBlockKey, block, OBJC_ASSOCIATION_COPY);
}
- (void)__handleActionForTapGesture:(UITapGestureRecognizer *)gesture
{
if (gesture.state == UIGestureRecognizerStateRecognized)
{
void(^action)(void) = objc_getAssociatedObject(self, &kDTActionHandlerTapBlockKey);
if (action)
{
action();
}
}
}
- (void)setLongPressActionWithBlock:(void (^)(void))block
{
UILongPressGestureRecognizer *gesture = objc_getAssociatedObject(self, &kDTActionHandlerLongPressGestureKey);
if (!gesture)
{
gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(__handleActionForLongPressGesture:)];
[self addGestureRecognizer:gesture];
objc_setAssociatedObject(self, &kDTActionHandlerLongPressGestureKey, gesture, OBJC_ASSOCIATION_RETAIN);
}
objc_setAssociatedObject(self, &kDTActionHandlerLongPressBlockKey, block, OBJC_ASSOCIATION_COPY);
}
- (void)__handleActionForLongPressGesture:(UITapGestureRecognizer *)gesture
{
if (gesture.state == UIGestureRecognizerStateBegan)
{
void(^action)(void) = objc_getAssociatedObject(self, &kDTActionHandlerLongPressBlockKey);
if (action)
{
action();
}
}
}
@end
//
// UIView+LineWithAutolayout.h
// ZhengXing
//
// Created by wangyang on 11/6/14.
// Copyright (c) 2014 Wanmei Creative. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIView (LineWithAutolayout)
/**
* @author licong, 16-12-28 19:12:48
*
* alloc一个无固定大小的view,用作分割线
*
* @return 返回一个view
*
* @since 5.8
*/
- (UIView *)addLineWithoutFrame;
/**
* @author licong, 16-12-28 19:12:16
*
* 在指定view(就是self)的最上边缘,加一根与指定view宽度相等的头部边缘线
*
* @return 返回alloc的分割线
*
* @since 5.8
*/
- (UIView *)addTopLine;
/**
* @author licong, 16-12-28 19:12:16
*
* 在view(就是self)的最下边缘,加一根与指定view宽度相等的底部边缘线
*
* @return 返回alloc的分割线
*
* @since 5.8
*/
- (UIView *)addBottomLine;
/**
* @author licong, 16-12-28 19:13:30
*
* 给指定的view(就是self),加一跟中心水平线
*
* @param left 竖直线距离设定的view左边的距离
* @param right 竖直线距离设定的view右边的距离
*
* @return 返回alloc的中心竖直线
*
* @since 5.8
*/
- (UIView *)addCenterHorizontalLineWithLeft:(CGFloat)left right:(CGFloat)right;
/**
* @author licong, 16-12-28 19:12:40
*
* 给指定的view(就是self),加一跟中心竖直线
*
* @param top 竖直线距离设定的view上边的距离
* @param bottom 竖直线距离设定的view下边的距离
*
* @return 返回alloc的中心竖直线
*
* @since 5.8
*/
- (UIView *)addCenterVerticalLineWithTop:(CGFloat)top bottom:(CGFloat)bottom;
/**
* @author licong, 16-12-28 19:12:19
*
* 给指定的view(就是self)的最下边缘,加一根长度可设置的头部边缘线(最长不超过该view的宽度)
*
* @param left 头部边缘线距离设定view左边的距离
* @param right 头部边缘线距离设定view左边的距离
*
* @return 返回长度可设置的头部边缘线
*
* @since 5.8
*/
- (UIView *)addTopLineWithLeft:(CGFloat)left right:(CGFloat)right;
/**
* @author licong, 16-12-28 19:12:16
*
* 给指定的view(就是self)的最下边缘,加一根长度可设置的底部边缘线(最长不超过该view的宽度)
*
* @param left 底部边缘线距离设定view左边缘的距离
* @param right 底部边缘线距离设定view右边缘的距离
*
* @return 返回长度可设置的底部边缘线
*
* @since 5.8
*/
- (UIView *)addBottomLineWithLeft:(CGFloat)left right:(CGFloat)right;
/**
* @author licong, 16-12-29 11:12:02
*
* 给指定的view(就是self),加一根长度可设置的水平线,以Top为Y方向的基准点
*
* @param top 水平线距离设定view上边缘的距离
* @param left 水平线距离设定view左边缘的距离
* @param right 水平线距离设定view右边缘的距离
*
* @return 返回水平线
*
* @since 5.8
*/
- (UIView *)addHorizontalLineWithTop:(CGFloat)top left:(CGFloat)left right:(CGFloat)right;
/**
* @author licong, 16-12-29 11:12:48
*
* 给指定的view(就是self),加一根长度可设置的水平线,以Bottom为Y方向的基准点
*
* @param bottom 水平线距离设定view下边缘的距离
* @param left 水平线距离设定view左边缘的距离
* @param right 水平线距离设定view右边缘的距离
*
* @return 返回水平线
*
* @since 5.8
*/
- (UIView *)addHorizontalLineWithBottom:(CGFloat)bottom left:(CGFloat)left right:(CGFloat)right;
/**
* @author licong, 16-12-29 11:12:48
*
* 给指定的view(就是self),加一根长度可设置的竖直线,以Left为X方向的基准点
*
* @param left 竖直线距离设定view左边缘的距离
* @param top 竖直线距离设定view上边缘的距离
* @param bottom 竖直线距离设定view下边缘的距离
*
* @return 返回竖直线
*
* @since 5.8
*/
- (UIView *)addVerticalLineWithLeft:(CGFloat)left top:(CGFloat)top bottom:(CGFloat)bottom;
/**
* @author licong, 16-12-29 11:12:54
*
* 给指定的view(就是self),加一根长度可设置的竖直线,以Right为X方向的基准点
*
* @param right 竖直线距离设定view右边缘的距离
* @param top 竖直线距离设定view上边缘的距离
* @param bottom 竖直线距离设定view下边缘的距离
*
* @return 返回竖直线
*
* @since 58
*/
- (UIView *)addVerticalLineWithRight:(CGFloat)right top:(CGFloat)top bottom:(CGFloat)bottom;
@end
//
// UIView+LineWithAutolayout.m
// ZhengXing
//
// Created by wangyang on 11/6/14.
// Copyright (c) 2014 Wanmei Creative. All rights reserved.
//
#import "UIView+LineWithAutolayout.h"
#import <Masonry/Masonry.h>
#import <UIColor+GMTheme.h>
@interface OnePixelLine : UIView
@end
@implementation OnePixelLine
@end
@implementation UIView (LineWithAutolayout)
- (UIView *)addLineWithoutFrame{
UIView *line = [OnePixelLine new];
line.backgroundColor = UIColor.separatorLine;
[self addSubview:line];
return line;
}
- (UIView *)addTopLine
{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(0);
make.left.mas_equalTo(0);
make.right.mas_equalTo(0);
make.height.offset(1/[UIScreen mainScreen].scale);
}];
return line;
}
- (UIView *)addBottomLine
{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(0);
make.left.mas_equalTo(0);
make.right.mas_equalTo(0);
make.height.offset(1/[UIScreen mainScreen].scale);
}];
return line;
}
- (UIView *)addCenterHorizontalLineWithLeft:(CGFloat)left right:(CGFloat)right{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(0);
make.left.mas_equalTo(left);
make.right.mas_equalTo(right);
make.height.offset(1/[UIScreen mainScreen].scale);
}];
return line;
}
- (UIView *)addCenterVerticalLineWithTop:(CGFloat)top bottom:(CGFloat)bottom{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(top);
make.centerX.mas_equalTo(0);
make.bottom.mas_equalTo(bottom);
make.width.offset(1/[UIScreen mainScreen].scale);
}];
return line;
}
- (UIView *)addTopLineWithLeft:(CGFloat)left right:(CGFloat)right{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(0);
make.left.mas_equalTo(left);
make.right.mas_equalTo(right);
make.height.offset(1/[UIScreen mainScreen].scale);
}];
return line;
}
- (UIView *)addBottomLineWithLeft:(CGFloat)left right:(CGFloat)right{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(0);
make.left.mas_equalTo(left);
make.right.mas_equalTo(right);
make.height.offset(1/[UIScreen mainScreen].scale);
}];
return line;
}
- (UIView *)addHorizontalLineWithTop:(CGFloat)top left:(CGFloat)left right:(CGFloat)right{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(top);
make.left.mas_equalTo(left);
make.right.mas_equalTo(right);
make.height.offset(1/[UIScreen mainScreen].scale);
}];
return line;
}
- (UIView *)addHorizontalLineWithBottom:(CGFloat)bottom left:(CGFloat)left right:(CGFloat)right{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(bottom);
make.left.mas_equalTo(left);
make.right.mas_equalTo(right);
make.height.offset(1/[UIScreen mainScreen].scale);
}];
return line;
}
- (UIView *)addVerticalLineWithLeft:(CGFloat)left top:(CGFloat)top bottom:(CGFloat)bottom{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(top);
make.left.mas_equalTo(left);
make.bottom.mas_equalTo(bottom);
make.width.offset(1/[UIScreen mainScreen].scale);
}];
return line;
}
- (UIView *)addVerticalLineWithRight:(CGFloat)right top:(CGFloat)top bottom:(CGFloat)bottom{
UIView *line = [self addLineWithoutFrame];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(top);
make.right.mas_equalTo(right);
make.bottom.mas_equalTo(bottom);
make.width.offset(1/[UIScreen mainScreen].scale);
}];
return line;
}
@end
//
// UIViewController+ChildSwitch.h
// segmentSwitch
//
// Created by wangyang on 5/13/15.
// Copyright (c) 2015 IGIU. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIViewController (ChildControllerSwitch)
#pragma mark - 只读属性
/**
当前显示的controller
*/
@property (nonatomic, strong) UIViewController *currentController;
/**
将childContainer添加到视图中用来显示所有的child
注意:childContainer只有一个子视图:childScrollView,childScrollView装载了所有的child。
*/
@property (nonatomic, strong) IBOutlet UIView *childContainer;
/**
用来横滑切换chile controller。可以使用childScrollView.scrollEnable来禁止。
其contentSize的高为childContainer.height
*/
@property (nonatomic, strong) UIScrollView *childScrollView;
/**
返回该类别所管理的chile view controllers
*/
@property (nonatomic, copy) NSArray *childs;
#pragma mark - 需要配置的属性
/**
childContainer的size,需要手动计算出来
*/
@property (nonatomic, assign) CGSize childContainerSize;
/**
滑动childScrollView,滑动停止,调用该block。典型使用就是通知segment切换到指定位置
*/
@property (nonatomic, copy) void (^childScrollViewDidEndScroll) (NSInteger index);
#pragma mark - 可选属性
/**
switchToChildControllerAtIndex后会调用
*/
@property (nonatomic, copy) void (^didFinishSwitchChild) (void);
#pragma mark - 方法
/**
* @brief 设置第一个要显示的controller
*
*/
- (void)setFirstController:(UIViewController *)controller;
/**
* @brief 添加待显示的controllers
*
*/
- (void)addOtherController:(NSArray *)otherControllers;
/**
设置第一个需要显示的controller及其它待显示的controllers
*/
- (void)setFirstController:(UIViewController *)controller otherController:(NSArray *)otherControllers;
/**
切换到指定位置的controller
*/
- (void)switchToChildControllerAtIndex:(NSUInteger)index;
@end
//
// UIViewController+ChildSwitch.m
// segmentSwitch
//
// Created by wangyang on 5/13/15.
// Copyright (c) 2015 IGIU. All rights reserved.
//
#import "UIViewController+ChildControllerSwitch.h"
#import <objc/runtime.h>
#import <Masonry/Masonry.h>
#import "UIView+Layout.h"
#import "Constant.h"
@interface NSObject (CustomClass)
@end
@implementation NSObject (CustomClass)
@end
@interface ScrollViewDelegate: NSObject <UIScrollViewDelegate>
@property (nonatomic, copy) void (^scrollViewEndScroll) (void);
@end
@implementation ScrollViewDelegate
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
if (self.scrollViewEndScroll) {
self.scrollViewEndScroll();
}
}
@end
@interface UIViewController ()
@property (nonatomic, strong) ScrollViewDelegate *scrollDelegate;
@end
@implementation UIViewController (ChildControllerSwitch)
/**
* set方法是为了适应IB,如果纯代码可以不用set方法
*/
- (void)setChildContainer:(UIView *)childContainer{
objc_setAssociatedObject(self, @selector(childContainer), childContainer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIView *)childContainer{
UIView *childContainer = objc_getAssociatedObject(self, _cmd);
if (!childContainer) {
childContainer = [[UIView alloc] init];
childContainer.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
objc_setAssociatedObject(self, _cmd, childContainer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return childContainer;
}
- (void)setCurrentController:(UIViewController *)currentController{
objc_setAssociatedObject(self, NSSelectorFromString(@"currentController"), currentController, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIViewController *)currentController{
return objc_getAssociatedObject(self, NSSelectorFromString(@"currentController"));
}
- (void)setChildScrollView:(UIScrollView *)childScrollView {
objc_setAssociatedObject(self, @selector(childScrollView), childScrollView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIScrollView *)childScrollView {
UIScrollView *_childScrollView = objc_getAssociatedObject(self, @selector(childScrollView));
if (_childScrollView == nil) {
_childScrollView = [UIScrollView new];
_childScrollView.delegate = self.scrollDelegate;
_childScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.childContainer addSubview:_childScrollView];
_childScrollView.pagingEnabled = YES;
_childScrollView.scrollsToTop = NO;
_childScrollView.showsHorizontalScrollIndicator = NO;
[_childScrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(UIEdgeInsetsZero);
}];
objc_setAssociatedObject(self, _cmd, _childScrollView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return _childScrollView;
}
- (void)setScrollDelegate:(ScrollViewDelegate *)scrollDelegate {
objc_setAssociatedObject(self, @selector(scrollDelegate), scrollDelegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (ScrollViewDelegate *)scrollDelegate {
ScrollViewDelegate *_scrollDelegate = objc_getAssociatedObject(self, @selector(scrollDelegate));
if (_scrollDelegate == nil) {
_scrollDelegate = [ScrollViewDelegate new];
__weak __typeof(self) weakSelf = self;
_scrollDelegate.scrollViewEndScroll = ^{
[weakSelf prepareChangeController];
};
objc_setAssociatedObject(self, _cmd, _scrollDelegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return _scrollDelegate;
}
- (void)setChildContainerSize:(CGSize)childContainerSize {
NSValue *size = [NSValue valueWithCGSize:childContainerSize];
objc_setAssociatedObject(self, @selector(childContainerSize), size, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
if (self.childs.count != 0) {
#warning 这个高度是否可以直接使用self.height
self.childScrollView.contentSize = CGSizeMake(childContainerSize.width * self.childs.count , childContainerSize.height);
}
}
- (CGSize)childContainerSize {
NSValue *size = objc_getAssociatedObject(self, @selector(childContainerSize));
if (size == nil) {
return CGSizeZero;
} else {
return [size CGSizeValue];
}
}
- (void)setChildScrollViewDidEndScroll:(void (^) (NSInteger))block {
objc_setAssociatedObject(self, @selector(childScrollViewDidEndScroll), block, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (void (^) (NSInteger))childScrollViewDidEndScroll {
id block = objc_getAssociatedObject(self, @selector(childScrollViewDidEndScroll));
return block;
}
- (void)setChilds:(NSArray *)childs {
objc_setAssociatedObject(self, @selector(childs), childs, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSArray *)childs {
NSArray *_childs = objc_getAssociatedObject(self, @selector(childs));
return _childs;
}
- (void)setDidFinishSwitchChild:(void (^) (void))block {
objc_setAssociatedObject(self, @selector(didFinishSwitchChild), block, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (void (^) (void))didFinishSwitchChild {
id block = objc_getAssociatedObject(self, @selector(didFinishSwitchChild));
return block;
}
#pragma mark - 方法
- (void)setFirstController:(UIViewController *)controller {
[self addForwardAppearanceMethods:controller];
self.childContainer.size = self.childContainerSize;
self.childScrollView.size = self.childContainerSize;
controller.view.frame = self.childContainer.bounds;
controller.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[self.childScrollView addSubview:controller.view];
self.currentController = controller;
[self addChildViewController:controller];
[self.currentController didMoveToParentViewController:self];
}
- (void)setFirstController:(UIViewController *)controller otherController:(NSArray *)otherControllers {
NSAssert(controller, @"不能设置nil为第一个controller");
NSAssert(self.childContainer.superview, @"self.childContainer must have a superview");
[self setFirstController:controller];
[self addOtherController:otherControllers];
}
- (void)addOtherController:(NSArray *)otherControllers {
NSAssert(self.currentController, @"不能设置nil为第一个controller");
for (UIViewController *other in otherControllers) {
[self addForwardAppearanceMethods:other];
[self addChildViewController:other];
}
self.childs = [[NSArray arrayWithObject:self.currentController] arrayByAddingObjectsFromArray:otherControllers];
CGSize size = CGSizeMake(self.childContainerSize.width * self.childs.count , self.childContainerSize.height);
self.childScrollView.contentSize = size;
}
- (void)addForwardAppearanceMethods:(UIViewController *)controller {
SEL sel = @selector(shouldAutomaticallyForwardAppearanceMethods);
IMP imp = imp_implementationWithBlock(^(){
return NO;
});
class_addMethod([controller class], sel, imp, "B@:");
}
- (void)switchToChildControllerAtIndex:(NSUInteger)index {
self.childScrollView.contentOffset = CGPointMake(index * self.childContainer.bounds.size.width, 0);
/*
比如A -> B -> A,因为A.view被添加到scrollView中就不会被移除,所以当再次回到A->B,或者B->A时,viewWillAppear等4个方法都不会调用
使用 beginAppearanceTransition:animated:、endAppearanceTransition 可以解决这个问题。
另外需要配合 shouldAutomaticallyForwardAppearanceMethods 使用。
beginAppearanceTransition:animated: 设置为YES触发Child View Controller的viewWillAppear;
beginAppearanceTransition:animated: 设置为NO触发Child View Controller的viewWillDisappear;
endAppearanceTransition 触发Child View Controller的viewDidAppear 和viewDidDisappear
*/
UIViewController *to = self.childViewControllers[index];
UIViewController *from = self.currentController;
if (to == from) {
if (self.didFinishSwitchChild) {
self.didFinishSwitchChild();
}
} else {
if (to.view.superview == nil) {
CGRect frame = self.childContainer.bounds;
frame.origin.x = frame.size.width * index;
frame.size = self.childContainer.size;
to.view.frame = frame;
to.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[self.childScrollView addSubview:to.view];
[from beginAppearanceTransition:NO animated:NO];
[to didMoveToParentViewController:self];
[from endAppearanceTransition];
} else {
[to beginAppearanceTransition:YES animated:NO];
[from beginAppearanceTransition:NO animated:NO];
[to endAppearanceTransition];
[from endAppearanceTransition];
}
self.currentController = to;
if (self.didFinishSwitchChild) {
self.didFinishSwitchChild();
}
}
}
- (void)prepareChangeController {
int index = self.childScrollView.contentOffset.x / self.childContainer.bounds.size.width;
[self switchToChildControllerAtIndex:index];
if (self.childScrollViewDidEndScroll) {
self.childScrollViewDidEndScroll(index);
}
}
@end
//
// UIColor+GMTheme.h
// Gengmei
// 主题
// Created by Thierry on 1/7/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#define RGBCOLOR_HEX(hexColor) [UIColor colorWithRed: (((hexColor >> 16) & 0xFF))/255.0f \
green: (((hexColor >> 8) & 0xFF))/255.0f \
blue: ((hexColor & 0xFF))/255.0f \
alpha: 1]
NS_ASSUME_NONNULL_BEGIN
@interface UIColor (GMTheme)
/** 医生版主视觉颜色,暂时改为红色,用来区分, (0x3ADBD2) */
@property (nonatomic, class, readonly) UIColor *mainVisual;
/** 医生版辅助颜色, (0xFF7690) */
@property (nonatomic, class, readonly) UIColor *secondaryVisual;
/** 医生版失效颜色, (0xD5D5D5) */
@property (nonatomic, class, readonly) UIColor *disable;
/** 医生版分割线颜色、边框颜色, (0xE5E5E5) */
@property (nonatomic, class, readonly) UIColor *separatorLine;
/** 医生版背景颜色, (0xF5F5F5) */
@property (nonatomic, class, readonly) UIColor *background;
/** 医生版提示背景颜色(黄), (0xF8F4DD) */
@property (nonatomic, class, readonly) UIColor *backgroundTip;
/** 医生版tag背景颜色, (0xF0F0F0) */
@property (nonatomic, class, readonly) UIColor *tagBackground;
/** 一级标题字、主要内容, (0x282828) */
@property (nonatomic, class, readonly) UIColor *headlineText;
/** 正文、普通文字内容, (0x464646) */
@property (nonatomic, class, readonly) UIColor *bodyText;
/** 可点击状态的文字更美绿, (0x4ABAB4) */
@property (nonatomic, class, readonly) UIColor *auxiliaryTextGreen;
/** 文字的更美红, (0xFF7690) */
@property (nonatomic, class, readonly) UIColor *auxiliaryTextRed;
/** 文字的更美黄提示色, (0x9D704F) */
@property (nonatomic, class, readonly) UIColor *auxiliaryTextYellow;
/** 辅助文字色, (0x666666) */
@property (nonatomic, class, readonly) UIColor *auxiliaryTextDark;
/** 辅助文字色, (0x999999) */
@property (nonatomic, class, readonly) UIColor *auxiliaryTextLight;
/** 辅助文字色, (0xcccccc) */
@property (nonatomic, class, readonly) UIColor *auxiliaryTextExtraLight;
/** 目前和MAIN_VISUAL_COLOR一样, (0x3ADBD2) */
@property (nonatomic, class, readonly) UIColor *buttonNormalGreen;
/** (0x1FB2A7) */
@property (nonatomic, class, readonly) UIColor *buttonHighlightGreen;
/** 目前和SECONDARY_VISUAL_COLOR一样, (0xFF7690) */
@property (nonatomic, class, readonly) UIColor *buttonNormalRed;
/** (0xE75873) */
@property (nonatomic, class, readonly) UIColor *buttonHighlightRed;
/** 目前和DISABLE_COLOR一样, (0xD5D5D5) */
@property (nonatomic, class, readonly) UIColor *buttonDisable;
/** 标签选中绿色, (0x24DAE0) */
@property (nonatomic, class, readonly) UIColor *tagSelectedGreen;
/**
用于色值是数字
*/
+ (UIColor *)colorWithHex:(NSInteger)hex;
+ (UIColor *)colorWithHex:(NSInteger)hex alpha:(CGFloat)alpha;
/**
用于色值字符串
*/
+ (UIColor *)colorWithHexString:(NSString *)hexString;
+ (UIColor *)colorWithHexString:(NSString *)hexString alpha:(CGFloat)alpha;
@end
NS_ASSUME_NONNULL_END
//
// UIColor+GMTheme.m
// GMKit
//
// Created by wangyang on 2017/11/8.
//
#import <UIColor+GMTheme.h>
//用户版色值
#ifdef IS_USER
//颜色规范
#define MAIN_VISUAL_COLOR RGBCOLOR_HEX(0x3ADBD2) //主视觉颜色
#define SECONDARY_VISUAL_COLOR RGBCOLOR_HEX(0xFF7690) //辅助颜色
#define SEPARATOR_LINE_COLOR RGBCOLOR_HEX(0xE5E5E5) //分割线颜色、边框颜色
#define BACKGROUND_COLOR RGBCOLOR_HEX(0xF4F3F8) //背景颜色
#define DISABLE_COLOR RGBCOLOR_HEX(0xD5D5D5) //失效颜色
#define BACKGROUND_TIP_COLOR RGBCOLOR_HEX(0xFFFBE4) //提示背景颜色(黄)
#define TAG_BACKGROUND_COLOR RGBCOLOR_HEX(0xF0F0F0) //tag背景颜色
#define TAG_SELECTED_COLOR RGBCOLOR_HEX(0x24DAE0)
//文字颜色
#define HEADLINE_TEXT_COLOR RGBCOLOR_HEX(0x282828) //一级标题字、主要内容
#define BODY_TEXT_COLOR RGBCOLOR_HEX(0x464646) //正文、普通文字内容
#define AUXILIARY_TEXT_GREEN RGBCOLOR_HEX(0x4ABAB4) //可点击状态的文字更美绿
#define AUXILIARY_TEXT_RED RGBCOLOR_HEX(0xFF7690) //文字的更美红
#define AUXILIARY_TEXT_YELLOW RGBCOLOR_HEX(0x9D704F) //文字的更美黄提示色
#define AUXILIARY_TEXT_COLOR_DARK RGBCOLOR_HEX(0x666666) //辅助文字色
#define AUXILIARY_TEXT_COLOR_LIGHT RGBCOLOR_HEX(0x999999) //辅助文字色
#define AUXILIARY_TEXT_COLOR_EXTRA_LIGHT RGBCOLOR_HEX(0xcccccc) //辅助文字色
//按钮颜色
#define BUTTON_NORMAL_GREEN_COLOR RGBCOLOR_HEX(0x3ADBD2) //目前和MAIN_VISUAL_COLOR一样
#define BUTTON_HIGHLIGHT_GREEN_COLOR RGBCOLOR_HEX(0x1FB2A7)
#define BUTTON_NORMAL_RED_COLOR RGBCOLOR_HEX(0xFF7690) //目前和SECONDARY_VISUAL_COLOR一样
#define BUTTON_HIGHLIGHT_RED_COLOR RGBCOLOR_HEX(0xE75873)
#define BUTTON_DISABLE_COLOR RGBCOLOR_HEX(0xD5D5D5) //目前和DISABLE_COLOR一样
//医生版色值,目前未支持
#elif IS_DOCTOR
//颜色规范
#define MAIN_VISUAL_COLOR RGBCOLOR_HEX(0x3ADBD2) //医生版主视觉颜色,暂时改为红色,用来区分
#define SECONDARY_VISUAL_COLOR RGBCOLOR_HEX(0xFF7690) //医生版辅助颜色
#define SEPARATOR_LINE_COLOR RGBCOLOR_HEX(0xE5E5E5) //医生版分割线颜色、边框颜色
#define DISABLE_COLOR RGBCOLOR_HEX(0xD5D5D5) //医生版失效颜色
#define BACKGROUND_COLOR RGBCOLOR_HEX(0xF5F5F5) //医生版背景颜色
#define BACKGROUND_TIP_COLOR RGBCOLOR_HEX(0xF8F4DD) //医生版提示背景颜色(黄)
#define TAG_BACKGROUND_COLOR RGBCOLOR_HEX(0xF0F0F0) //医生版tag背景颜色
#define TAG_SELECTED_COLOR RGBCOLOR_HEX(0x24DAE0) //tag标签选中颜色
//文字颜色
#define HEADLINE_TEXT_COLOR RGBCOLOR_HEX(0x282828) //一级标题字、主要内容
#define BODY_TEXT_COLOR RGBCOLOR_HEX(0x464646) //正文、普通文字内容
#define AUXILIARY_TEXT_GREEN RGBCOLOR_HEX(0x4ABAB4) //可点击状态的文字更美绿
#define AUXILIARY_TEXT_RED RGBCOLOR_HEX(0xFF7690) //文字的更美红
#define AUXILIARY_TEXT_YELLOW RGBCOLOR_HEX(0x9D704F) //文字的更美黄提示色
#define AUXILIARY_TEXT_COLOR_DARK RGBCOLOR_HEX(0x666666) //辅助文字色
#define AUXILIARY_TEXT_COLOR_LIGHT RGBCOLOR_HEX(0x999999) //辅助文字色
#define AUXILIARY_TEXT_COLOR_EXTRA_LIGHT RGBCOLOR_HEX(0xcccccc) //辅助文字色
//按钮颜色
#define BUTTON_NORMAL_GREEN_COLOR RGBCOLOR_HEX(0x3ADBD2) //目前和MAIN_VISUAL_COLOR一样
#define BUTTON_HIGHLIGHT_GREEN_COLOR RGBCOLOR_HEX(0x1FB2A7)
#define BUTTON_NORMAL_RED_COLOR RGBCOLOR_HEX(0xFF7690) //目前和SECONDARY_VISUAL_COLOR一样
#define BUTTON_HIGHLIGHT_RED_COLOR RGBCOLOR_HEX(0xE75873)
#define BUTTON_DISABLE_COLOR RGBCOLOR_HEX(0xD5D5D5) //目前和DISABLE_COLOR一样
#else //这里的默认色值可以随意,默认填的是用户板的色值
//颜色规范
#define MAIN_VISUAL_COLOR RGBCOLOR_HEX(0x3ADBD2) //主视觉颜色
#define SECONDARY_VISUAL_COLOR RGBCOLOR_HEX(0xFF7690) //辅助颜色
#define SEPARATOR_LINE_COLOR RGBCOLOR_HEX(0xE5E5E5) //分割线颜色、边框颜色
#define BACKGROUND_COLOR RGBCOLOR_HEX(0xF4F3F8) //背景颜色
#define DISABLE_COLOR RGBCOLOR_HEX(0xD5D5D5) //失效颜色
#define BACKGROUND_TIP_COLOR RGBCOLOR_HEX(0xFFFBE4) //提示背景颜色(黄)
#define TAG_BACKGROUND_COLOR RGBCOLOR_HEX(0xF0F0F0) //tag背景颜色
#define TAG_SELECTED_COLOR RGBCOLOR_HEX(0x24DAE0) //tag标签选中颜色
//文字颜色
#define HEADLINE_TEXT_COLOR RGBCOLOR_HEX(0x282828) //一级标题字、主要内容
#define BODY_TEXT_COLOR RGBCOLOR_HEX(0x464646) //正文、普通文字内容
#define AUXILIARY_TEXT_GREEN RGBCOLOR_HEX(0x4ABAB4) //可点击状态的文字更美绿
#define AUXILIARY_TEXT_RED RGBCOLOR_HEX(0xFF7690) //文字的更美红
#define AUXILIARY_TEXT_YELLOW RGBCOLOR_HEX(0x9D704F) //文字的更美黄提示色
#define AUXILIARY_TEXT_COLOR_DARK RGBCOLOR_HEX(0x666666) //辅助文字色
#define AUXILIARY_TEXT_COLOR_LIGHT RGBCOLOR_HEX(0x999999) //辅助文字色
#define AUXILIARY_TEXT_COLOR_EXTRA_LIGHT RGBCOLOR_HEX(0xcccccc) //辅助文字色
//按钮颜色
#define BUTTON_NORMAL_GREEN_COLOR RGBCOLOR_HEX(0x3ADBD2) //目前和MAIN_VISUAL_COLOR一样
#define BUTTON_HIGHLIGHT_GREEN_COLOR RGBCOLOR_HEX(0x1FB2A7)
#define BUTTON_NORMAL_RED_COLOR RGBCOLOR_HEX(0xFF7690) //目前和SECONDARY_VISUAL_COLOR一样
#define BUTTON_HIGHLIGHT_RED_COLOR RGBCOLOR_HEX(0xE75873)
#define BUTTON_DISABLE_COLOR RGBCOLOR_HEX(0xD5D5D5) //目前和DISABLE_COLOR一样
#endif
@implementation UIColor (GMTheme)
/**
用于色值是数字
*/
+ (UIColor *)colorWithHex:(NSInteger)hex{
return [UIColor colorWithHex:hex alpha:1.0];
}
+ (UIColor *)colorWithHex:(NSInteger)hex alpha:(CGFloat)alpha{
CGFloat r = ((hex & 0xFF0000) >> 16) / 255.0;
CGFloat g = ((hex & 0x00FF00) >> 8) / 255.0;
CGFloat b = ((hex & 0x0000FF) >> 0) / 255.0;
return [UIColor colorWithRed:r green:g blue:b alpha:alpha];
}
/**
用于色值字符串
*/
+ (UIColor *)colorWithHexString:(NSString *)hexString{
return [UIColor colorWithHexString:hexString alpha:1.0];
}
+ (UIColor *)colorWithHexString:(NSString *)hexString alpha:(CGFloat)alpha{
unsigned int hex = 0;
NSScanner * scanner = [NSScanner scannerWithString:hexString];
if([scanner scanHexInt:&hex]){
return [UIColor colorWithHex:(NSInteger)hex alpha:alpha];
}else{
return [[UIColor alloc]init];
}
}
/**
色值库里的各种色值
*/
+ (UIColor *)mainVisual{
return MAIN_VISUAL_COLOR;
}
+ (UIColor *)secondaryVisual{
return SECONDARY_VISUAL_COLOR;
}
+ (UIColor *)disable{
return DISABLE_COLOR;
}
+ (UIColor *)separatorLine{
return SEPARATOR_LINE_COLOR;
}
+ (UIColor *)background{
return BACKGROUND_COLOR;
}
+ (UIColor *)backgroundTip{
return BACKGROUND_TIP_COLOR;
}
+ (UIColor *)tagBackground{
return TAG_BACKGROUND_COLOR;
}
+ (UIColor *)headlineText{
return HEADLINE_TEXT_COLOR;
}
+ (UIColor *)bodyText{
return BODY_TEXT_COLOR;
}
+ (UIColor *)auxiliaryTextGreen{
return AUXILIARY_TEXT_GREEN;
}
+ (UIColor *)auxiliaryTextRed{
return AUXILIARY_TEXT_RED;
}
+ (UIColor *)auxiliaryTextYellow{
return AUXILIARY_TEXT_YELLOW;
}
+ (UIColor *)auxiliaryTextDark{
return AUXILIARY_TEXT_COLOR_DARK;
}
+ (UIColor *)auxiliaryTextLight{
return AUXILIARY_TEXT_COLOR_LIGHT;
}
+ (UIColor *)auxiliaryTextExtraLight{
return AUXILIARY_TEXT_COLOR_EXTRA_LIGHT;
}
+ (UIColor *)buttonNormalGreen{
return BUTTON_NORMAL_GREEN_COLOR;
}
+ (UIColor *)buttonHighlightGreen{
return BUTTON_HIGHLIGHT_GREEN_COLOR;
}
+ (UIColor *)buttonNormalRed{
return BUTTON_NORMAL_RED_COLOR;
}
+ (UIColor *)buttonHighlightRed{
return BUTTON_HIGHLIGHT_RED_COLOR;
}
+ (UIColor *)buttonDisable{
return BUTTON_DISABLE_COLOR;
}
+ (UIColor *)tagSelectedGreen {
return TAG_SELECTED_COLOR;
}
@end
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
//
// GMImageView.h
// Gengmei
//
// Created by Thierry on 2/12/15.
// Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface GMImageView : UIImageView
- (void)setImageWithUrlString:(NSString *)urlString placeHolder:(NSString *)placeHolder;
@end
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment