質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

1回答

634閲覧

SWIFTライブラリ:PaperSwitchのコードでの利用

masayoshi555

総合スコア9

TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2020/01/16 21:07

編集2020/01/17 20:40

困りごと

swiftのライブラリ:PaperSwitchをtableViewで使いたく、
tableViewにコードで実装するUISwitchをPaperSwitchにしたいと考えています。
*PaperSwitchについては最下段に記載しています

以下のコードではswitchが表示されず困っています。
どなたかご教授頂けると幸いです。

import UIKit import RAMPaperSwitch class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { override func viewDidLoad() { super.viewDidLoad() } // セル数の設定 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 5 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // セルを取得する tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell") let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) cell.textLabel!.text = "test" //UISwitchをcellのアクセサリービューに追加する let switchView = UISwitch(frame: CGRect(x: (self.view.frame.width) / 2, y: (self.view.frame.height) / 2 , width: 50, height: 25)) as? RAMPaperSwitch cell.accessoryView = switchView //ティントカラーを指定 switchView?.onTintColor = UIColor.blue return cell } }

実行結果

エラーは出ませんが、Switchが表示されません
イメージ説明

as? RAMPaperSwitchを除くと表示される

コード内「let switchView = UISwitch(frame: CGRect(省略) / 2 , width: 50, height: 25)) as? RAMPaperSwitch」から「as? RAMPaperSwitch」を除くと以下のようにswitchが表示されますが、PaperSwitchは適用されない。(当たり前ですね)
イメージ説明

事前に宣言してから使用

では、事前に宣言してはどうかと思い試しましたが、

let switchView: RAMPaperSwitch? switchView = UISwitch(frame: CGRect(x: (self.view.frame.width) / 2, y: (self.view.frame.height) / 2 , width: 50, height: 25)) cell.accessoryView = switchView

「Cannot assign value of type 'UISwitch' to type 'RAMPaperSwitch?'」と表示され
FIX候補として「Insert ' as! RAMPaperSwitch'」が表示されます。
その通りにして実行すると、エラーとなります。

let switchView: RAMPaperSwitch? switchView = UISwitch(frame: CGRect(x: (self.view.frame.width) / 2, y: (self.view.frame.height) / 2 , width: 50, height: 25)) as! RAMPaperSwitch cell.accessoryView = switchView

error

1Could not cast value of type 'UISwitch' (0x7fff898b23a0) to 'RAMPaperSwitch.RAMPaperSwitch' (0x110049c98).

RAMPaperSwitch classを編集(2020/1/18 05:30追記)

以下に記載のRAMPaperSwitch class内のUIViewであるが故に、
今回のcellでは表示できないのではないかと思い、UIView(3箇所)を全てUITableViewCellに変更し
実行しましたが、switchは表示されませんでした。

public required init(view: UIView?, color: UIColor?) { super.init(frame: CGRect.zero) onTintColor = color self.commonInit(view) }

その際、ここにエラーが出たのでsuperview as? UITableViewCellとしました

override open func awakeFromNib() { self.commonInit(parentView ?? superview) super.awakeFromNib() }

###PaperSwitch
PaperSwitch自体は本来storyboardで配置したswitchのclassをRAMPaperSwitchと
指定し、onTintColorを指定するだけで利用できると言う優れものです。
通常の使い方(view内)での作動は確認できております。
イメージ説明
イメージ説明
イメージ説明

open class RAMPaperSwitch: UISwitch, CAAnimationDelegate { struct Constants { static let scale = "transform.scale" static let up = "scaleUp" static let down = "scaleDown" } /// The total duration of the animations, measured in seconds. Default 0.35 @IBInspectable open var duration: Double = 0.35 /// Closuer call when animation start open var animationDidStartClosure = {(onAnimation: Bool) -> Void in } /// Closuer call when animation finish open var animationDidStopClosure = {(onAnimation: Bool, finished: Bool) -> Void in } fileprivate var shape: CAShapeLayer! = CAShapeLayer() fileprivate var radius: CGFloat = 0.0 fileprivate var oldState = false fileprivate var defaultTintColor: UIColor? @IBOutlet open var parentView: UIView? { didSet { defaultTintColor = parentView?.backgroundColor } } // MARK: - Initialization /** Returns an initialized switch object. - parameter view: animatable view - parameter color: The color which fill view. - returns: An initialized UISwitch object. */ public required init(view: UIView?, color: UIColor?) { super.init(frame: CGRect.zero) onTintColor = color self.commonInit(view) } public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } override open func awakeFromNib() { self.commonInit(parentView ?? superview) super.awakeFromNib() } // MARK: Helpers fileprivate func commonInit(_ parentView: UIView?) { guard let onTintColor = self.onTintColor else { fatalError("set tint color") } self.parentView = parentView defaultTintColor = parentView?.backgroundColor layer.borderWidth = 0.5 layer.borderColor = UIColor.white.cgColor layer.cornerRadius = frame.size.height / 2 shape.fillColor = onTintColor.cgColor shape.masksToBounds = true parentView?.layer.insertSublayer(shape, at: 0) parentView?.layer.masksToBounds = true showShapeIfNeed() addTarget(self, action: #selector(RAMPaperSwitch.switchChanged), for: UIControl.Event.valueChanged) } override open func layoutSubviews() { if let parentView = self.parentView { let x:CGFloat = max(center.x, parentView.frame.size.width - frame.midX) let y:CGFloat = max(center.y, parentView.frame.size.height - frame.midY) radius = sqrt(x*x + y*y) } let additional = parentView == superview ? CGPoint.zero : (superview?.frame.origin ?? CGPoint.zero) shape.frame = CGRect(x: center.x - radius + additional.x - 2, y: center.y - radius + additional.y, width: radius * 2, height: radius * 2) shape.anchorPoint = CGPoint(x: 0.5, y: 0.5) shape.path = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: radius * 2, height: radius * 2)).cgPath } // MARK: - Public open override func setOn(_ on: Bool, animated: Bool) { let changed:Bool = on != self.isOn super.setOn(on, animated: animated) if changed { switchChangeWithAnimation(animated) } } // MARK: - Private fileprivate func showShapeIfNeed() { shape.transform = isOn ? CATransform3DMakeScale(1.0, 1.0, 1.0) : CATransform3DMakeScale(0.0001, 0.0001, 0.0001) } @objc internal func switchChanged() { switchChangeWithAnimation(true) } // MARK: - Animations fileprivate func animateKeyPath(_ keyPath: String, fromValue from: CGFloat?, toValue to: CGFloat, timing timingFunction: String) -> CABasicAnimation { let animation:CABasicAnimation = CABasicAnimation(keyPath: keyPath) animation.fromValue = from animation.toValue = to animation.repeatCount = 1 animation.timingFunction = CAMediaTimingFunction(name: convertToCAMediaTimingFunctionName(timingFunction)) animation.isRemovedOnCompletion = false animation.fillMode = CAMediaTimingFillMode.forwards animation.duration = duration animation.delegate = self return animation } fileprivate func switchChangeWithAnimation(_ animation: Bool) { guard let onTintColor = self.onTintColor else { return } shape.fillColor = onTintColor.cgColor if isOn { let scaleAnimation:CABasicAnimation = animateKeyPath(Constants.scale, fromValue: 0.01, toValue: 1.0, timing:convertFromCAMediaTimingFunctionName(CAMediaTimingFunctionName.easeIn)); if animation == false { scaleAnimation.duration = 0.0001 } shape.add(scaleAnimation, forKey: Constants.up) } else { let scaleAnimation:CABasicAnimation = animateKeyPath(Constants.scale, fromValue: 1.0, toValue: 0.01, timing:convertFromCAMediaTimingFunctionName(CAMediaTimingFunctionName.easeOut)); if animation == false { scaleAnimation.duration = 0.0001 } shape.add(scaleAnimation, forKey: Constants.down) } } //MARK: - CAAnimation Delegate open func animationDidStart(_ anim: CAAnimation) { parentView?.backgroundColor = defaultTintColor animationDidStartClosure(isOn) } open func animationDidStop(_ anim: CAAnimation, finished flag: Bool) { if flag == true { parentView?.backgroundColor = isOn == true ? onTintColor : defaultTintColor } animationDidStopClosure(isOn, flag) } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

UISwitch(frame: CGRect(x: (self.view.frame.width) / 2, y: (self.view.frame.height) / 2 , width: 50, height: 25))
と書いたら、RAMPaperSwitchではなく、UISwitchが生成されます。

とりあえず、RAMPaperSwitchを生成するには、
RAMPaperSwitch(frame: CGRect(x: (self.view.frame.width) / 2, y: (self.view.frame.height) / 2 , width: 50, height: 25))
とする必要があると思います。

ただ、RAMPaperSwitchのGitHubのUsageやデモアプリには、コードで利用する方法は書かれてなかったので、これでうまくいくかどうかは知りません。

うまくいかないなら、コードで利用するのではなく、Storyboardで利用した方が良いと思います。Storyboardを使ってセルのAccessoryViewにSwitchを設置するには、次の方法でできます。
https://wayohoo.com/programming/objective-c/how-to-set-the-accessoryView-of-uitableviewcell-in-storyboard.html

投稿2020/01/18 02:32

TakeOne

総合スコア6299

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masayoshi555

2020/01/18 20:13

TakeOneさん ご回答ありがとうございます。 ご提案の件ですが、以下のエラーとなります。 「Cannot invoke initializer for type 'RAMPaperSwitch' with no arguments」 やはり、ご指摘通りStoryboard利用しかできないのかもしれないですね。 セルをユーザーの操作に応じて動的に増やしたいので、switchをコード実装しなければいけないと考えています。 やはり、PaperSwitchは諦めた方が良さそうですね。
TakeOne

2020/01/19 01:48

「セルをユーザーの操作に応じて動的に増やしたい」だけで、どうしてStoryboardが使えないのかわかりませんでした。普通にStoryboardのTableViewの中にセルを定義し、そのセルを表示する数やセルの内容をコードで制御すればいいだけのように思います。状況に応じてRAMPaperSwitchを表示したりしなかったりするのであれば、isHiddenで非表示にするような制御をすればいいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問