徒然:陽気のせいか疲れやすい

寒暖差に身体が負けています。

体調不良とまではいかないのですが、時々、横になって休まないときょう一日を乗り切れません。それは疲れたという感覚と違い、だるさが身体の芯から湧き上がり、外に出きれないまま、また、身体の中に戻って沈着してしまう感じです。

抗がん剤治療としては軽い方だと思いますが、きっと、薬の副作用はこんなふうに現れるものなのでしょうね。あと5ヶ月で服薬が終わるので、もう少しの我慢です。

医者には、体重が増えたこと、むくみがあること、疲れやすいことについて説明しています。それで、薬の量を減らし、服用日数と休む日数を緩和したり、必要な措置はされています。

それでも、きっと百歳くらいまで生きるのだろうと話しています。毎月、血液検査をし、健康管理をしてもらっているからです。インフルエンザの注射をした看護師さんは、定期検診はしなくていいですよ、と言っていました。

やれやれです。

百歳まで生きるとなると、何をして生きるか、またもや考えないといけません。老若男女を問わず、生きるということがなんなのか、全く解決されていないのに、またこのテーマが立ちはだかります。しかし、ある日、道端にノートが落ちていて、それに自分の人生の全てが書き込まれていたら、もっと悲しい結果になる気もします。

すると、生きるということは過去に向けてではなく、未来に向けて開かれているだけだ、とそんなふうにも思えてきます。未来は単に可能性の総和なのでしょう。

近所

Swift4:UITableViewRowAction

tableViewの行の削除orその行が保有するURLのwebページ読み込みをどうすればいいか考えてました。

簡単な方法がありました。

注意しないといけない点は、対象行にアラート表示した後でaction以下が再度起動されることです。つまり、次の通り。

◾️class MesaModalArea
//0ID 1 2 3Date 4URL 5folder 6file 7Title 8Favicon 9Undo 10Data
var rcArray:[NSMutableDictionary]= []
var rcUpdateSign:String     = “”      //Write MesaClip file or Not(“”).
var maybeLastRow:Int        = 0       //Current rcArray-row-number.
var qRow:Int                = 0       //target row number.

 

◾️class MesaTable
@IBOutletweakvar  yTableView:UITableView!    //tableView
var wkSelectedRow:Int = -1                   //work: Selected row number.
let Z = MesaModalArea.sharedInstance         //Common area.

 

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath)//
-> [UITableViewRowAction]? {                   //
wkSelectedRow         = indexPath.row        //Set selected row number.
let wRead = UITableViewRowAction(style:.normal, title:”Read”) {//🔴🔴Read URL
(action, indexPath) in                       //
self.Z.bookmarkURL = self.Z.rcArray[self.wkSelectedRow][self.Z.fURL] as! String//
self.yTableView.reloadData()                 //Reload the table.
self.ExecClose(sender: self)                 //Close and Exit.
}                                              //
wRead.backgroundColor   = UIColor.blue       //Change background color.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
let wDelete = UITableViewRowAction(style:.default, title:”Delete”) {//🔴🔴Remove
(action, indexPath) in                       //
self.Z.rcArray.remove(at: indexPath.row)   //Remove this row.
self.Z.rcUpdateSign     = “up”             //Write MesaClip file.
tableView.deleteRows(at:[indexPath], with:.fade)//
if self.wkSelectedRow – 1  >= 0  {         //
self.Z.qRow = self.wkSelectedRow – 1       //Current row = Previous row.
} else if self.Z.rcArray.count > 0 { self.Z.qRow = 0}  //Current row = Next row.
else                               { self.Z.qRow = -1 }//Current row = NA
self.Z.maybeLastRow    = self.Z.qRow       //Current row number.
//var _:IndexPath = IndexPath(row: Z.qRow, section: indexPath.count)//
if self.Z.qRow >= 0 {                      //
tableView.selectRow(at: IndexPath(row: self.Z.qRow, //Select row.
section: 1), animated: true, scrollPosition: .middle)//
}  else { }                                //
self.yTableView.reloadData()               //Reload the table.
}                                            //
wDelete.backgroundColor = UIColor.red        //
return [wRead, wDelete]                      //
}//

Screenshot 2018-03-07 08.27.06

Swift4:Swipe

Swipeを実装しました。無償版からwordpress.comプレミアムに変更しました。

長押しをどうするかまだ決めていませんが、Swipeは実装しました。

課題は、iPhoneの場合、Swipeできる箇所、簡単にSwipeができる場所が決まっているようです。ある記事では、適用領域が狭いという指摘がありました。

しかし、使えなくはないので、実装したままで行きたいと考えています。

Swipe sample: .right / .left / .down
let wRightSwipe = UISwipeGestureRecognizer(target:self,     //
action:#selector(ExecForward(sender:)))                     //右 次のページwRightSwipe.numberOfTouchesRequired = 1                     //
wRightSwipe.direction   = .right                            //
let wLeftSwipe  = UISwipeGestureRecognizer(target:self,     //
action:#selector(ExecBackward(sender:)))                    //左 前のページ
wLeftSwipe.numberOfTouchesRequired = 1                      //
wLeftSwipe.direction    = .left                             //
let wDownSwipe  = UISwipeGestureRecognizer(target:self,     //
action:#selector(ExecBackward(sender:)))                    //下 前のページ
wDownSwipe.numberOfTouchesRequired = 1                      //
wDownSwipe.direction    = .down                             //
self.view.addGestureRecognizer(wRightSwipe)                 //登録する。
self.view.addGestureRecognizer(wLeftSwipe)                  //登録する。
self.view.addGestureRecognizer(wDownSwipe)                  //登録する。

@IBAction func ExecForward(sender:UISwipeGestureRecognizer) {   //<*次のページに*>
ExecIBActionForward(self)                                       //
}//————————————————————-//
@IBAction func ExecBackward(sender:UISwipeGestureRecognizer) {  //<*前のページに*>
ExecIBActionBackward(self)                                      //
}//————————————————————-//
@IBAction func ExecReload(sender:UISwipeGestureRecognizer) {    //<*前のページに*>
ExecIBActionBackward(self)                                      //
//  ExecIBActionReload(self)                                    //
}//————————————————————-//

この事例では、swipeできる領域はtoolbarの中に限られます。いろいろ試してみたのですが、self.viewではそうなるようです。なお、numberOfTouchesRequiredのデフォルトは1で定義してもしなくても問題ないですが、明示的に定義した方がわかりやすいと思います。

Screenshot 2018-03-03 23.30.48

 

Swift4:大きなアイコン

Toolbarに大きなアイコンを表示するにはどうすればいいの?

摩訶不思議な謎がひとつ解けました。

前々から不思議に思っていたのですが、今になってようやくやり方がわかりました。

絵文字ならフォントサイズを大きくすればいいです。NSImageのアイコンの場合、ずっとなぜ小さいのだろうと不思議に思っていたわけです。

アイコンが小さいとクリックがうまくいかないのは、それなりの問題がありました。

Screenshot 2018-03-02 21.02.04

Swift4:UISwitchかUIButtonか?

便利そうだったのでUISwitchを実装したのですが、想定した通りではありませんでした。

またしても未熟さが露見してしまいました。

UISwitchでON/OFFを選択した直後に@IBActionにトリガーがかかればリアルタイムに言語をひとつだけ選択できるのですが、用途はONにした言語を全部有効にする機能の方が実装されていました。これだと英語か日本語をひとつだけ有効にする場合、うまくありません。

それで、UIBottonを透明化してクリックされたらONとOFFを交互にする仕様とすることで、やりたいことを実現しました。

このとき、文字色で判定するようにしたのですが、色をColorsからcopy and pasteでソースコードに貼り付けられることをはじめて知りました。やれやれです。

Screenshot 2018-03-02 20.47.29

Screenshot 2018-03-02 20.47.40

Swift4:管理情報のsave / restore

アプリの管理管理情報のsave / restoreに関するメモです。

アプリを終了するときの状態をsaveし、再起動するときにrestoreして終了時の状態から再開させるには、ファイルをどこに保存すればいいか、どんなファイルタイプが許されるか、iOSにはOpenPanelがないので、どうしたものかとずっと考えていました。

これは思いのほか、簡単でした。

  • var wDocDirectry = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!//ディレクトリ
  • let wFilepath:String  = wDocDirectry + “/” + “Mesaclip.mesa”//MesaClip管理ファイル

むしろ、NSDataのwrite / readと配列への戻し方に手間取りました。

  • let wArray:[Any]  = NSKeyedUnarchiver.unarchiveObject(with: wData! as Data)! as? NSArray as! [Any]//NSDataをNSDictionaryに変換する。
  • Z.rcArray = NSKeyedUnarchiver.unarchiveObject(with: wArray[0] as! Data) as! [NSMutableDictionary]//00 メモ(rcArray)
  • Z.maybeLastRow  = wArray[1] as! Int  //01 現在選択されいる表の行位置
  • Z.xLanguage.setTitle(wArray[2] as? String, for: .normal) //02 言語

Screenshot 2018-02-28 11.56.00

  • bookmarkファイルはmacOSで作成し、iOSにcopy and pasteする仕様としました。
  • 将来的には、icloudにした方がいい、と考えています。MesaMeterをアップデートするときに再検討することにします。

Swift4:iOSのfavicon

iOSはfaviconをサポートしていません。

少し悲しい気がしますが、大勢に影響はありません。iOSのSafariもサポートしておらず、アイコンは一様でした。macOSでは苦労して設定しただけに力が抜けてしまいました。

Swift4:モーダルの制御の仕方

storyboardで定義したそれぞれのモーダル画面を制御するときのひとつのアイデアです。

単にモーダルアラートを表示したり、メイン(ViewController)側で指示した通りにモーダル画面を表示する場合でも、

  • メイン側の画面の内容を参照したい。たとえば、ボタンに意味を持たせているようなケースでは同じボタン表示をしたいし、言語ボタンの内容が英語と日本語のどちらかなどの判定をしたい。
  • 呼び出し元でそれぞれのモーダル画面に対して何回も同じ内容を設定しないといけないのは面倒。

というような問題があります。

問題解決のためのアイデア: 共通エリア

  1. ひとつは、各モーダル画面のclassの中で受け渡しパラメータを定義せず、モーダル共用エリアを定義することで、それぞれのモーダル画面・機能に対して共有できるパラメータと固有パラメータを引き渡すことができます。
  2. こうすることで、子側で親側の画面を参照できます。また、機能的な独立性をどう担保するかという問題はありますが、ほかのモーダル画面・機能で設定した内容も参照したり、変更することができます。

もうひとつは、

  • モーダル画面側でユーザーが設定した内容により、自動的に次の画面を表示したい場合、たとえば、エンコード選択なら、次のURL読み込みに間に合えばいいので結果だけ返せばいいのですが、ブックマークを選択するモーダル画面では、URLを決定したら、ただちにその画面を表示する必要があります。

問題解決のためのアイデア: プログレスタイマー

  1. プログレスのタイマー管理で子側のモーダル画面側で設定するパラメータを監視することでこの問題は解決できます。
  2. たとえば、子側がブックマークを選択するモーダル画面でURLを決定したら、プログレスのタイマー管理で変化を監視してこのURLを読み込むようにしておけば、問題解決です。

Screenshot 2018-02-28 09.16.08

@IBOutlet weak var xProgress: UIProgressView! //プログレス

Screenshot 2018-02-28 10.33.37

共通エリア(呼び出し元処理はほかのモーダルと同じ)

Screenshot 2018-02-28 10.44.48

共通エリア

Screenshot 2018-02-28 10.49.32