2019年6月30日 星期日

iOS swift 5: NotificationCenter 的用法

 可以用於不同的畫面傳遞參數
 也可以用於Thread中程式, 通知Main Thread 更新畫面的動作

 解決方案來源:
  Swift - 透過 NotificationCenter 監聽特定的事件同時傳值


 override func viewDidLoad()
 {  
  MyFunNtfInit()
 } 
 func MyFunNtfInit()
 {
  NotificationCenter.default.addObserver(forName: Notification.Name(rawValue: "MYFUNNTF"),
    object: nil, queue: nil, using: MyFunNtf)
 }
 
 func MyFunNtfPost()
 {
  NotificationCenter.default.post(name: Notification.Name(rawValue: "MYFUNNTF"),
            object: nil, userInfo: ["MSG1":"F","MSG1":"MyMsg2"])
 }
 
 @onjc fileprivate func MyFuncThread
 {
  while( 1)
  {
   if( bDoNtfPost == true)
   {
    MyFunNtfPost()
   }
  }
 }
 
 func MyFunNtf(noti:Notification) -> Void
 {
  guard let userInfo = noti.userInfo,
    let sMsg1 = userInfo["MSG1"] as? String,
    let sMsg2  = userInfo["MSG2"] as? String else {
       return
    }
   if( sMsg1 == "MyMsg1" ) 
   {
    ...
   }
 }    


2019年6月28日 星期五

iOS swift 5: Function的多參數傳入及回傳



 解決方案來源:
  Function with multiple parameters and multiple return values

func greetUser(name:String, age:Int) -> (String, Int) {
    
    let msg = "Good Morning!" + name
    var userage = age
    if age < 0
    {
     userage = 0
    }
    return (msg, userage)
}
 let msg = greetUser(name: "Jack", age: -2)
 print(msg.0)
 print("You have \(msg.1) coins left")

2019年6月27日 星期四

iOS swift 5: 直接移除字串中不是數字的字元

字串中不是數字的直接移除
 解決方案來源:
  Filter non-digits from string

 sStrTmp2 = sStrTmp1.components(separatedBy:CharacterSet.decimalDigits.inverted).joined(separator: "")
 if( sStrTmp2.count > 0)
 {
  if let nNumber = Int(sStrTmp2)
  {
  }
 } 

字串的字元檢查
  sStrTmp1 = "0123456789"
  for nChar in sStrTmp1  /* 檢查是否為數字字元 */
  {
   if( nChar < "0" || nChar > "9")
   {
    bIsNumber = false
   }
  }

iOS swift 5: HEX ASCII 字串轉換為Int

HEX ASCII 字串轉換為Int
 解決方案來源:
  Swift Int 轉 16進位字串、16進位字串轉 Int
  Swift native functions to have numbers as hex strings

 func MyFunA()
 {
  let sStr1 = "7FFF"
  let nInt = strHex2Int(sStr1)
  print( nInt)
  let sStr2 = Int2strHex( nInt).uppercased() // 轉大寫
  print( sStr2)
 }
 
 func strHex2Int(_ strHex:String) -> Int
 { /* 16進位字串轉Int */
  let nInt = Int(strHex, radix: 16)
  return nInt!
 }

 func Int2strHex(_ int:Int)-> String
 { /* Int轉16進位字串 */
  let sStr = String(int, radix: 16)
  return sStr
 }

iOS swift 5: 數字陣列 Int Array

數字陣列 Int Array

Int Array 宣告方式
宣告 nSeqAvgArr 有9個 Integer陣列
並都初始化為 0x00

  var nSeqAvgArr = Array( repeating: 0, count:9)

 func MyFunA()
 {
  var nInArr = Array( repeating: 0, count:9)
  _ = MyFunB( &nInArr)
  print( nInArr.count )
  print( nInArr[0] )
  _ = MyFunC( &nInArr)
  print( nInArr.count )
  print( nInArr[0] )
 }

 func MyFunB(_ nInArr: inout [Int]) -> Bool
 {
  nInArr[0] = 1234
  ...
  return false
 }

 func MyFunC(_ nInArr: [Int]) -> Bool
 {
  nInArr[0] = 1234
  ...
  return false
 }








iOS swift 5: 字串的切割分離

iOS swift 5: 字串的切割分離

 解決方案來源:
  A Unicode string value that is a collection of characters.
  Swift Arrays
  Split a String into an array in Swift?

字串的切割分離
import Foundation
let fullName : String = "First Last";
let fullNameArr : [String] = fullName.componentsSeparatedByString(" ")

// And then to access the individual words:

var firstName : String = fullNameArr[0]
var lastName : String = fullNameArr[1]


  let sStr:String = "0,0001,0010,0100,1000,1023,0001,0001,0001"
  
  let sStrArr = sStr.components(separatedBy: ",")
  print( sStrArr.count )
  print( sStrArr[0] )
  ...
  print( sStrArr[6] )









2019年6月23日 星期日

iOS swift 5: 主執行緒或是背景執行緒


  主執行緒 DispatchQueue.main.async
  背景執行緒 DispatchQueue.global().async

 解決方案來源:
  Swift 3學習指南:重新認識GCD應用


DispatchQueue.main.async
{
 // 用於UI類
  self.MyBtn.setImage(UIImage(named: "MyBtnImage"), for: UIControl.State.normal)
}


let MY_TIMEOUT             = 100
let MySimaphore = DispatchSemaphore.init( value: 0)
MyThreadCreate()
{

hMyThread = Thread( target: self,
                       selector: #selector( MyThreadFunc), object: nil)
}

MyThreadFunc()
{
 ...
 DispatchQueue.global().async
 {
  //在 Thread中 用於 DispatchSemaphore類
  self.MySimaphore.signal()
 }
 ...
 if( MySimaphore.wait(timeout: .now() + .seconds(MY_TIMEOUT)) == .success)
 {
  ...
 }
 else
 {
  ...
 }
 
} 


2019年6月21日 星期五

iOS swift 5: 學習Swifte 一定要先弄懂 GCD,Delegates,dataSource


 解決方案來源:
  【給iOS新手】Delegate是啥?能吃嗎?
 
  Delegate 是什麼? 
 
  iOS 開發者指南:透過 Swift 4 學習 Delegates 與 Delegation
 

程式流成為了達到 A功能完成後,才能再執行B功能,再執行C功能
在 BCB 中使用 showmodal()就解決了
但在 iOS 中會是滿麻煩的事
建議使用下面兩種方式來達成

 iOS - GCD 多執行緒的說明與應用
 iOS開發之再探多線程編程:Grand Central Dispatch詳解
 JS - Promise使用詳解1(基本概念、使用優點)
 Swift - 異步編程庫PromiseKit使用詳解1(安裝配置、基本用法)

2019年6月20日 星期四

iOS swift 5: 關於 Debug Mode prinf function

iOS swift 5: 關於 Debug Mode prinf function

 swift 沒有C++的 redefine function 功能
 所以只能下面方式來暫用
 另一種方式使用 swift 內建的 debugPrint()

 解決方案來源:
  Swift: Extending functionality of print() function
  STRIPPING PRINT AND DEBUGPRINT IN SWIFT FOR RELEASE BUILDS
  Swift print, println, NSLog

public func debugPrint(_ items: Any..., separator: String = " ", terminator: String = "\n")

import Foundation
public func DPrint(_ items: Any..., separator: String = " ", terminator: String = "\n") 
{
 #if DEBUG // for Debug Mode
  let output = items.map { "\($0)" }.joined(separator: separator)
  Swift.print(output, terminator: terminator)
 #else     // for Relase Mode
  // ...
 #endif
}
public func RPrint(_ items: Any..., separator: String = " ", terminator: String = "\n") 
{
 #if DEBUG // for Debug Mode
 #else     // for Relase Mode
  let output = items.map { "\($0)" }.joined(separator: separator)
  Swift.print(output, terminator: terminator)
 #endif
}

import Foundation
class MyViewController: UIViewController 
{
  func MyFun()
  {
   print("FUNC: \(#file),\(#function)")
   debugPrint("FUNC: \(#file),\(#function)")
   DPrint("FUNC: \(#file),\(#function)")
   RPrint("FUNC: \(#file),\(#function)")
  }
}


2019年6月19日 星期三

iOS swift 5: 關於 bits shift

iOS swift 5: 關於 bits shift

 swift 沒有C++的 struct bit 對照
 所以只能用 bits shift 來一個一個處理
 解決方案來源:
  How do I shift bits using Swift?

  Bitwise Shifting (swift 3)
// Shifting Right
let example1 = 8 >> 1 // example1 == 4
let example2 = 8 >> 2 // example2 == 2
// Shifting Left
let example3 = 8 << 1 // example3 == 16
let example4 = 8 << 2 // example4 == 32
 let N1 = 1 << 0 // 0b0001
 let N2 = 1 << 1 // 0b0010
 let N3 = N1 & N2  // => 0b0000
 let N4 = N1 | N2  // => 0b0011


iOS swift 5: 在 Thread中 要呼叫另一個畫面

iOS swift 5: Thread And self.present

 解決方案來源:
   Xcode 9 的 Main Thread Checker

簡單的說如果在 Thread中 要呼叫另一個畫面
要使用 DispatchQueue.main.async 方法

Main Thread Checker: UI API called on a background thread: -[UIButton setImage:forState:]
PID: 1284, TID: 896227, Thread name: (none), Queue name: com.apple.root.default-qos.overcommit, QoS: 0

  DispatchQueue.main.async
  {
   let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
   let ShowVc = storyBoard.instantiateViewController(withIdentifier: "ShowVcId") as! TShowVc
   ShowVc.TitleStr = Title 
   self.present( ShowVc, animated: true, completion: nil)
  }   

iOS swift 5: 取得iOS設備型號

iOS swift 5: 設備型號
 解決方案來源:
  iOS獲取設備型號和App版本號等信息(OC+Swift)

    //  獲取設備名稱
    let deviceName = UIDevice.current.name
    print(deviceName)
    // 系統名稱
    let systemName = UIDevice.current.systemName
    print(systemName)
    // 系統版本
    let sysVersion = UIDevice.current.systemVersion
    print(sysVersion)
    // 設備的型號
    let sysmodel = UIDevice.current.model
    print(sysmodel)
    // 獲取設備唯一標識符
    let sUuid = UIDevice.current.identifierForVendor?.uuidString
    print( sUuid ?? "")
   

2019年6月17日 星期一

iOS swift 5: 簡易的的替換式密碼ROT13

 解決方案來源:
  Swift ROT13 Func - Dot Net Perls


func rot13(value: String) -> String 
{ /* https://www.dotnetperls.com/rot13-swift */
    // Empty character array.
    var result = [Character]()
    // Some ASCII constants.
    // A = 65
    // M = 77
    // Z = 90
    // a = 97
    // m = 109
    // z = 122
    let upperA = 65
    let upperM = 77
    let upperZ = 90
    let lowerA = 97
    let lowerM = 109
    let lowerZ = 122

    // Loop over utf8 values in string.
    for u in value.utf8 {

        let s = Int(u)
        var resultCharacter = Character(UnicodeScalar(s))
        if s >= lowerA && s <= lowerZ { // Between a and z.
            if s >= lowerM {
                resultCharacter = Character(UnicodeScalar(s - 13))
            } else {
                resultCharacter = Character(UnicodeScalar(s + 13))
            }
        } else if s >= upperA && s <= upperZ { // Between A and Z.
            if s >= upperM {
                resultCharacter = Character(UnicodeScalar(s - 13))
            } else {
                resultCharacter = Character(UnicodeScalar(s + 13))
            }
        }
        // Append to Character array.
        result.append(resultCharacter)

    }
    // Return String.
    return String(result)
}



iOS swift 5: 對話框 Show Message Box(Dialog)-UIAlertController


Swift 顯示警告訊息有兩種方式

解決方案來源:
  iOS - 客製化Dialog
  PopupDialog:採用Swif編寫的一個簡單、可定製的iOS彈出對話框
  UIAlertController  顯示警告訊息和選單

方式一
 使用 UIAlertController
 使用 CustomAlertController範例
 UIAlertController 教程:讓你輕鬆在 UIViewController 以外的地方呈現警告
 Making an Alert in iOS

方式二
 使用  PopupDialog
 import PopupDialog
 func ShowMessageBoxDlg( nTitle:Int, nMessage:Int)
 { 
  let Title = NSLocalizedString( String(nTitle), comment: "")
  let Message = NSLocalizedString( String(nMessage), comment: "")
  let PopupDlg = PopupDialog( title: Title,
                           message: Message,
                           buttonAlignment: .horizontal,
                           transitionStyle: .zoomIn,
                           tapGestureDismissal: true,
                           panGestureDismissal: true,
                           hideStatusBar: true)
   {
   }
   let MagOk = NSLocalizedString( "Ok", comment: "")
   let buttonOk = DefaultButton(title: MagOk)
   {
   }
   PopupDlg.addButtons([buttonOk])
   self.present( PopupDlg, animated: true, completion: nil)
 }

方式三
 自行用 UIViewController 設計一個 Dialog
 畫面部份同  iOS - 客製化Dialog
 多花點時間 就可以做出一個和Windows 一樣的MessageBob()

import UIKit
//-------------------------------------------------------------------
var bShowWaitDialogClose: Bool = false
//-------------------------------------------------------------------
class TShowWaitDialogVc: UIViewController
{
 var nCheckCloseDialogTimer:Timer?
 var sTitleStr:String      = ""
 var sMessageStr:String    = ""

 var activityIndicator:UIActivityIndicatorView = UIActivityIndicatorView()

 @IBOutlet weak var ViewDialog: UIView!
 @IBOutlet weak var LabelTitleStr: UILabel!
 @IBOutlet weak var LabelMsgStr: UILabel!
 //-------------------------------------------------------------------
 override func viewDidLoad()
 {
  super.viewDidLoad()
  bShowWaitDialogClose = false
  let yourColor : UIColor = UIColor(red:170.0/255.0, green:170.0/255.0, blue:170.0/255.0, alpha: 1.0 )
  ViewDialog.layer.masksToBounds = true
  ViewDialog.layer.borderColor = yourColor.cgColor
  ViewDialog.layer.cornerRadius = 30
  ViewDialog.layer.borderWidth = 2
  ViewDialog.layer.shadowOffset = CGSize(width: 5, height: 5)
  ViewDialog.layer.shadowOpacity = 0.7
  ViewDialog.layer.shadowRadius = 5
  ViewDialog.layer.shadowColor = UIColor(red:170.0/255.0, green:170.0/255.0, blue:170.0/255.0, alpha: 1.0 ).cgColor

  LabelTitleStr.text = sTitleStr
  LabelMsgStr.text = sMessageStr
  CheckCloseDialogTimerInit()
  ActivityIndicatorStart()
 }
 //-------------------------------------------------------------------
 func CheckCloseDialogTimerInit()
 {
  nCheckCloseDialogTimer = Timer.scheduledTimer(timeInterval: 0.2, target: self,
                           selector:#selector(self.CheckCloseDialogTimerDown),
                           userInfo: nil, repeats: true)
 }
 //-------------------------------------------------------------------
 @objc func CheckCloseDialogTimerDown()
 {
  if( bShowWaitDialogClose == true)
  {
   self.nCheckCloseDialogTimer?.invalidate()
   ActivityIndicatorStop()
   dismiss(animated: true, completion: nil)
  }
 }
 //-------------------------------------------------------------------
 @objc func ActivityIndicatorStart()
 {
  activityIndicator.center = self.view.center

  activityIndicator.hidesWhenStopped = false
  activityIndicator.style = UIActivityIndicatorView.Style.gray
  activityIndicator.isHidden = false
  view.addSubview(activityIndicator)

  activityIndicator.startAnimating()
  UIApplication.shared.beginIgnoringInteractionEvents()
 }
 //-------------------------------------------------------------------
 @objc func ActivityIndicatorStop()
 {
  self.activityIndicator.stopAnimating()
  self.activityIndicator.isHidden = true
  UIApplication.shared.endIgnoringInteractionEvents()
 }
 //-------------------------------------------------------------------
}
//-------------------------------------------------------------------


    func ShowWaitDialogVcShow()
    {
     bShowWaitDialogClose = false
     let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
     let ShowWaitDialogVc = storyBoard.instantiateViewController(withIdentifier: "ShowWaitDialogVcID") as! TShowWaitDialogVc
     ShowWaitDialogVc.sTitleStr = "Processing"
     ShowWaitDialogVc.sMessageStr = "In Processing, Please Wait..."
     self.present( ShowWaitDialogVc, animated: true, completion: nil)
    }


 func BtnCloseDialg(_ sender: Any)
 {
  print("FUNC: \(#file), \(#function)")
  bShowWaitDialogClose = true
 }



    var hBtnTouchTimer:Timer?
    @IBAction func BtnTestOnClick(_ sender: Any)
    {
     bShowWaitDialogClose = false
     hBtnTouchTimer = Timer.scheduledTimer( timeInterval: 20, target: self,
                                            selector:#selector( self.BtnTouchTimerDown2),
                                            userInfo: nil, repeats: false)
     ShowWaitDialogVcShow()
    }
    @objc func BtnTouchTimerDown2()
    {
     if( bShowWaitDialogClose == false)
      bShowWaitDialogClose = true
    }

iOS swift 5: 顯示gif 動畫圖片

試玩這套 滿有趣的

解決方案來源:
  用QuartzCode快速實現一個收藏動畫


測試玩玩看
QuartzCode 1.66.4

另還有一套 PaintCode 3.4.5

2019年6月10日 星期一

2019年6月5日 星期三

iOS swift 5: 關於 "String Array"


Swift 的 String 是一個Class Library
當宣告為 var MyStringList = [String]() 時
就變成一個類似 String List Clss

解決方案來源:
 Swift Array Examples, String Arrays - Dot Net Perls


另一種方案是用 swift queue 方法
解決方案來源:
 Swift4 Day96:資料結構 Queues
 Swift數據結構-隊列Queue
 原始程式: Queue-Optimized.swift



2019年6月3日 星期一

iOS swift 5: About "Unprintable ASCII character found in source file"

"Unprintable ASCII character found in source file"
有一些中文字在 swift String Source Code中就會發生

解決方案來源:
  iOS - 關於多國語系的那些事(Localization)
  iOS - 在 App 內切換語系

解決方法
 把中文字串放到 Localizable.strings中
  \zh-Hant.lproj\Localizable.strings
 再使用 NSLocalizedString() 取出
  let MyStriug = NSLocalizedString("56022", comment: "")