git config --global core.editor 'vim -c "set fenc=utf-8"'
これでOK。
git config --global core.editor 'vim -c "set fenc=utf-8"'
UIUserNotificationType types = UIUserNotificationTypeBadge |
UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *mySettings = [UIUserNotificationSettings
settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
- (void)application:(UIApplication *)application
didRegisterUserNotificationSettings:
(UIUserNotificationSettings *)notificationSettings {
// user has allowed receiving user notifications of the following types
UIUserNotificationType allowedTypes = [notificationSettings types];
}
- (void)getReadyForNotification {
// ...
// check to make sure we still need to show notification
UIUserNotificationSettings *currentSettings = [[UIApplication
sharedApplication] currentUserNotificationSettings];
[self checkSettings:currentSettings];
}
UIMutableUserNotificationAction *acceptAction =
[[UIMutableUserNotificationAction alloc] init];
acceptAction.identifier = @"ACCEPT_IDENTIFIER";
acceptAction.title = @"Accept";
// Given seconds, not minutes, to run in the background
// UIUserNotificationActivationModeForegroundを指定すると、選択時にアプリを起動する
acceptAction.activationMode = UIUserNotificationActivationModeBackground;
acceptAction.destructive = NO;
// If YES requires passcode, but does not unlock the device
acceptAction.authenticationRequired = NO;
UIMutableUserNotificationCategory *inviteCategory =
[[UIMutableUserNotificationCategory alloc] init];
inviteCategory.identifier = @"INVITE_CATEGORY";
[inviteCategory setActions:@[acceptAction, maybeAction, declineAction]
forContext:UIUserNotificationActionContextDefault];
UIUserNotificationActionContextDefault ボタンのサイズが普通
UIUserNotificationActionContextMinimal ボタンのサイズが若干小さめNSSet *categories = [NSSet setWithObjects:inviteCategory, alarmCategory, ...
UIUserNotificationSettings *settings =
[UIUserNotificationSettings settingsForTypes:types categories:categories];
[[UIApplication sharedApplication]
registerUserNotificationSettings:settings];
{
"aps" : {
"alert" : "You’re invited!",
"category" : "INVITE_CATEGORY",
}
}
UILocalNotification *notification = [[UILocalNotification alloc] init];
...
notification.category = @"INVITE_CATEGORY";
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
application:didFinishLaunchingWithOptions:
application:didReceiveRemoteNotification:fetchCompletionHandler:
アプリが起動している場合はapplication:didReceiveLocalNotification:
application:didReceiveRemoteNotification:
application:didReceiveRemoteNotification:fetchCompletionHandler:
iOS8では// Push Notificationの場合
- (void)application:(UIApplication *)application
handleActionWithIdentifier:(NSString *)identifier
forRemoteNotification:(NSDictionary *)notification
completionHandler:(void (^)())completionHandler {
if ([identifier isEqualToString:@"ACCEPT_IDENTIFIER"]) {
[self handleAcceptActionWithNotification:notification];
}
// Must be called when finished
completionHandler();
}
// Local Notificationの場合
- (void)application:(UIApplication *)application
handleActionWithIdentifier:(NSString *)identifier
forLocalNotification:(UILocalNotification *)notification
completionHandler:(void(^)())completionHandler {
}
を使う。identifireにActionで選択されたIDが入ってくる。UILocalNotification * locNotification;
locNotification.regionTriggersOnce = YES;
locNotification.region = [[CLCircularRegion alloc] initWithCenter:LOC_COORDINATE
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
Use Command_R as KANA/EISUU (toggle)
iOSアプリ開発において、UXなどインタラクティブな操作において、
微妙なパラメータ調整を行いたい場合、簡単に設定画面を作って、再度ビルドすることなく、
値を変更して動作確認するためのライブラリです。(たぶん)
FacebookのPaperでも使われているそうです。
https://github.com/facebook/Tweaks
pod 'Tweaks'
引数は、カテゴリ、コレクション、名前、値(複数)
CGFloat animationDuration = FBTweakValue(@"Category", @"Group", @"Duration", 0.5);
※リリースビルドではデフォルト値を展開するだけなので、パフォーマンス的に問題にはならない
数字に対しては、値を複数していして、デフォルト値、最小値、最大値を指定することができる
self.red = FBTweakValue(@"Header", @"Colors", @"Red", 0.5, 0.0, 1.0);
微調整のパラメータが変更されたら自動で更新されます。
第一引数に対象のオブジェクト、第2引数にプロパティーを指定します。
FBTweakBind(self.headerView, alpha, @"Main Screen", @"Header", @"Alpha", 0.85);
微調整リストを選択したときの処理をBlockを使って定義する事ができる。
ただし、block内はグローバルスコープになる
FBTweakAction(@"Player", @"Audio", @"Volume", ^{
NSLog(@"Action selected.");
});
設定画面を表示する方法2種類
AppDelegate.mに以下を追加
- (UIWindow *)window
{
if (!_window) {
_window = [[FBTweakShakeWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
}
return _window;
}
シミュレータでシェイクジェスチャをする場合は⌘Z
モーダルで呼び出す。FBTweakViewController自体がNavigation Controllerなので、pushするとクラッシュする
FBTweakViewController* vc = [[FBTweakViewController alloc] initWithStore:[FBTweakStore sharedInstance]];
[self presentViewController:vc animated:YES completion:nil];
マクロを使わずに直接オブジェクトを生成する事も可能
FBTweak *tweak = [[FBTweak alloc] initWithIdentifier:@"com.tweaks.example.advanced"];
tweak.name = @"Advanced Settings";
tweak.defaultValue = @NO;
FBTweakStore *store = [FBTweakStore sharedInstance];
FBTweakCategory *category = [store tweakCategoryWithName:@"Settings"];
FBTweakCollection *collection = [category tweakCollectionWithName:@"Enable"];
[collection addTweak:tweak];
[tweak addObserver:self];
変更通知
- (void)tweakDidChange:(FBTweak *)tweak
{
self.advancedSettingsEnabled = ![tweak.currentValue boolValue];
}
ちょっとパラメータで調整したいなーと思う事はこったUIを作る場合や、複数人(デザイナーさんがいる)場合に遭遇する事があります。そのときにわざわざ設定画面を作る事無くマクロ一つで作成できるのはものすごーく魅力的に思います。
いざリリースするときにコードにゴミが残るのが少し気になりそうですが、実際に使ってみてある程度パラメータが固まったら削除するすれば良いし、このライブラリが無ければ、都度ビルドするとなるとそっちの方が行けてないなーと思いました。
bowerでライブラリ管理している前提です。
$ bower install angular-loading-bar --save
自分の環境ではangular-animateがなかったので、
angular-animateもインストールしました。
$ bower install angular-animate --save
app.jsなどで読み込むモジュールを宣言すればOK
angular.module('myApp', ['chieffancypants.loadingBar', 'ngAnimate'])
インジケータやローディングバーなど非表示にしたい場合。
Safariだとオリジナルのローディンブバーとかぶってちょっとださなかったので、
ローディングバーを非表示にしました。
angular.module('myApp', ['chieffancypants.loadingBar'])
.config(function(cfpLoadingBarProvider) {
cfpLoadingBarProvider.includeSpinner = false;
})
angular.module('myApp', ['chieffancypants.loadingBar'])
.config(function(cfpLoadingBarProvider) {
cfpLoadingBarProvider.includeBar = false;
})
すごく簡単にライブラリの追加が簡単になってます。
このライブラリを使ったアプリはこちら
pod 'Helpshift', '4.2.0'
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// ... 省略
[Helpshift installForApiKey:@"<YOUR_API_KEY>" domainName:@"<YOUR_COMPANY>.helpshift.com" appID:@"<YOUR_APP_ID>"];
if (launchOptions != nil) //handle when app is not in background and opened for push notification.
{
NSDictionary* userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (userInfo != nil && [[userInfo objectForKey:@"origin"] isEqualToString:@"helpshift"])
{
[[Helpshift sharedInstance] handleRemoteNotification:userInfo withController:self.window.rootViewController];
}
}
}
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
if (!deviceToken) return;
[[Helpshift sharedInstance] registerDeviceToken:deviceToken];
}
- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
//Helpshift::handle notification from APN
if ([[userInfo objectForKey:@"origin"] isEqualToString:@"helpshift"]) {
[[Helpshift sharedInstance] handleRemoteNotification:userInfo withController:self.window.rootViewController];
}
}
[[Helpshift sharedInstance] showConversation:self withOptions:nil];
メッセージ投稿フォームが起動するSETTINGS > Allow anonymous issues
[[Helpshift sharedInstance] showFAQs:self withOptions:nil];
Pods/Helpshift/helpshift-ios-4.2.0/HSLocalization
10種類の言語ファイルがあるので、必要なやつだけ追加する。Pods/Helpshift/helpshift-ios-4.2.0/HSThemes
全体的なデザインはデフォルトのままなので、あまり気にならないが、フォントだけどうしてもきになったので、
すべてヒラギノに変更UIViewControllerAnimatedTransitioningを継承したクラス
@interface HYFadeAnimationController : NSObject <UIViewControllerAnimatedTransitioning>
@end
実装はheaderファイル通り
アニメーション時間を指定
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext;
実際のアニメーションを指定
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
// 遷移元と遷移先のViewControllerを取得
UIViewController* fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController* toVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
// 遷移先のViewを追加
UIView* containerView = [transitionContext containerView];
[containerView insertSubview:toVC.view belowSubview:fromVC.view];
// アニメーションを指定
[UIView animateWithDuration:[self transitionDuration:transitionContext]
animations:^{
fromVC.view.alpha = 0.0;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
fromVC.view.alpha = 1.0;
}];
}
どの遷移で、どのアニメーションコントローラを利用するか指定する(今回は遷移元に実装)
@interface HYViewController () <UIViewControllerTransitioningDelegate>
@end
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"showModalView"]) {
[[segue destinationViewController] setTransitioningDelegate:self];
}
}
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController: (UIViewController *)dismissed
{
return [[HYFadeAnimationController alloc] init];
}
前提 ReactNativeでiOS版のアプリをリリースしていて、Android版をリリースする話 トラブルシューティング Build.VERSION_CODES.Q が存在しないエラー compileSdkVersionを29以上にすると解決 メモリー足りないエラー Execu...