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

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

ただいまの
回答率

90.34%

  • Swift

    7678questions

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

[Swift4] コードで設定したグラデーションレイヤーを取り除きたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 505

tyobigorou

score 547

いつもお世話になります。

StroyBoardで設置したUIButtonに、コード上でグラデーションレイヤーを設定し、
設定したレイヤーをとりのぞいてボタンを初期状態に戻したいのですが、どのようにすればよいでしょうか?

↓これでグラデーションを追加

// ボタン背景にグラデーションを変更する関数
    func changeSelectedButtonBackground (Button: UIButton) {
        // 選択されたボタンのグラデーション色を設定する
        let topColor = UIColor.hex(hexStr: "AAAAAA", alpha: 1.0)
        let bottomColor = UIColor.hex(hexStr: "686868", alpha: 1.0)
        //グラデーションの色を配列で管理
        let gradientColors: [CGColor] = [topColor.cgColor, bottomColor.cgColor]
        //グラデーションレイヤーを作成
        let gradientLayer: CAGradientLayer = CAGradientLayer()
        //グラデーションの色をレイヤーに割り当てる
        gradientLayer.colors = gradientColors
        //グラデーションレイヤーを対象ボタンのサイズにする
        gradientLayer.frame = Button.bounds
        //グラデーションレイヤーを配置  index(0)に追加しているので、index指定で削除できたら今後自由度高くなるから嬉しい
        Button.layer.insertSublayer(gradientLayer, at: 0)
    }


↓この関数で特定ボタンのグラデーションを解除したいが、StoryBoardでも背景にグラデーションを掛けてるのでそれもきえてるのかな?


    // ボタン背景のグラデーションを取り除く関数
    func removeGradientFromButtonBackground (Button: UIButton) {
        Button.layer.sublayers = nil
    }

↓下記を実行した際のプリントログ

// ボタン背景のグラデーションを取り除く関数
    func changeDefaultButtonBackground (Button: UIButton) {
        //Button.layer.sublayers?.remove(at: 0)
        if let layer = Button.layer.sublayers?.first {
            print("Button.layer.sublayers:",Button.layer.sublayers)
            layer.removeFromSuperlayer()
        }
    }

Button.layer.sublayers: 

Optional([<CAGradientLayer:0x168666f0; position = CGPoint (31.75 13.5); 
bounds = CGRect (0 0; 63.5 27); allowsGroupOpacity = YES; zPosition = -100; 
cornerRadius = 1; colors = (
"<CGColor 0x155c9e90> [<CGColorSpace 0x1565cdb0> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; sRGB IEC61966-2.1; extended range)] ( 0.121569 0.129412 0.141176 1 )",
"<CGColor 0x15591600> [<CGColorSpace 0x15560350> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; Generic Gray Gamma 2.2 Profile; extended range)] ( 0.407819 1 )")>, 

<CAGradientLayer:0x156755f0; position = CGPoint (31.75 13.25); bounds = CGRect (0 0; 63.5 26.5); allowsGroupOpacity = YES; colors = (
"<CGColor 0x156f9400> [<CGColorSpace 0x1565cdb0> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; sRGB IEC61966-2.1; extended range)] ( 0.666667 0.666667 0.666667 1 )",
"<CGColor 0x15665b00> [<CGColorSpace 0x1565cdb0> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; sRGB IEC61966-2.1; extended range)] ( 0.407843 0.407843 0.407843 1 )")>,

<CALayer:0x1683fd20; position = CGPoint (0 0); bounds = CGRect (0 0; 0 0); delegate = <UIImageView: 0x155294f0; frame = (0 0; 0 0); 
clipsToBounds = YES; alpha = 0.2; hidden = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1683fd20>>; hidden = YES; masksToBounds = YES; allowsGroupOpacity = YES; opacity = 0.2>, 

<_UILabelLayer:0x155aa940; position = CGPoint (31.75 13.75); bounds = CGRect (0 0; 51.5 11.5); delegate = <UIButtonLabel: 0x155a0ee0; frame = (6 8; 51.5 11.5); text = 'CLIPLINES'; alpha = 0.2; opaque = NO; 
userInteractionEnabled = NO; 

layer = <_UILabelLayer: 0x155aa940>>; contents = <CABackingStore 0x15789090 (buffer [123 23] BGRA8888)>; allowsGroupOpacity = YES; opacity = 0.2; contentsMultiplyColor = (null); rasterizationScale = 2; contentsScale = 2>, 

<CALayer:0x1683d990; position = CGPoint (59.5 22.5);bounds = CGRect (0 0; 2 2); delegate = <UIView: 0x155295f0; frame = (58.5 21.5; 2 2); layer = <CALayer: 0x1683d990>>; allowsGroupOpacity = YES; 
backgroundColor = <CGColor 0x156af0f0> [<CGColorSpace 0x15560350> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; Generic Gray Gamma 2.2 Profile; extended range)] ( 1 1 )>, 

<CALayer:0x16840460; position = CGPoint (59.5 22.5); bounds = CGRect (0 0; 2 2); delegate = <UIView: 0x155296d0; frame = (58.5 21.5; 2 2); 
layer = <CALayer: 0x16840460>>; 
allowsGroupOpacity = YES; 
backgroundColor = <CGColor 0x156af0f0> [<CGColorSpace 0x15560350> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; Generic Gray Gamma 2.2 Profile; extended range)] ( 1 1 )>, 

<CALayer:0x1552d0b0; position = CGPoint (59.5 22.5); bounds = CGRect (0 0; 2 2); delegate = <UIView: 0x1552cfd0; frame = (58.5 21.5; 2 2); layer = <CALayer: 0x1552d0b0>>; allowsGroupOpacity = YES; 
backgroundColor = <CGColor 0x156af0f0> [<CGColorSpace 0x15560350> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; Generic Gray Gamma 2.2 Profile; extended range)] ( 1 1 )>, 

<CALayer:0x1561e380; position = CGPoint (59.5 22.5); bounds = CGRect (0 0; 2 2); delegate = <UIView: 0x15651c50; frame = (58.5 21.5; 2 2); layer = <CALayer: 0x1561e380>>; 
allowsGroupOpacity = YES; backgroundColor = <CGColor 0x156af0f0> [<CGColorSpace 0x15560350> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; Generic Gray Gamma 2.2 Profile; extended range)] ( 1 1 )>, 

<CALayer:0x156662e0; position = CGPoint (59.5 22.5);bounds = CGRect (0 0; 2 2);delegate = <UIView: 0x15666200;frame = (58.5 21.5; 2 2); 
layer = <CALayer: 0x156662e0>>; allowsGroupOpacity = YES; 
backgroundColor = <CGColor 0x156af0f0> [<CGColorSpace 0x15560350> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; Generic Gray Gamma 2.2 Profile; extended range)] ( 1 1 )>, 

<CALayer:0x157da490; position = CGPoint (59.5 23); bounds = CGRect (0 0; 2 2); delegate = <UIView: 0x157da3b0; frame = (58.5 22; 2 2); 
layer = <CALayer: 0x157da490>>; allowsGroupOpacity = YES; 
backgroundColor = <CGColor 0x156af0f0> [<CGColorSpace 0x15560350> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; Generic Gray Gamma 2.2 Profile; extended range)] ( 1 1 )>,

<CALayer:0x157daa10; position = CGPoint (59.5 23); bounds = CGRect (0 0; 2 2); delegate = <UIView: 0x157da930; frame = (58.5 22; 2 2); 
layer = <CALayer: 0x157daa10>>; allowsGroupOpacity = YES;
backgroundColor = <CGColor 0x156af0f0> [<CGColorSpace 0x15560350> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; Generic Gray Gamma 2.2 Profile; extended range)] ( 1 1 )>, 

<CALayer:0x1564b150; position = CGPoint (59.5 23); bounds = CGRect (0 0; 2 2); delegate = <UIView: 0x1565fc20; frame = (58.5 22; 2 2); 
layer = <CALayer: 0x1564b150>>; allowsGroupOpacity = YES; 
backgroundColor = <CGColor 0x156af0f0> [<CGColorSpace 0x15560350> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; Generic Gray Gamma 2.2 Profile; extended range)] ( 1 1 )>, 

<CALayer:0x16868830; position = CGPoint (59.5 23); bounds = CGRect (0 0; 2 2); delegate = <UIView: 0x15531c30; frame = (58.5 22; 2 2); 
layer = <CALayer: 0x16868830>>; allowsGroupOpacity = YES; 
backgroundColor = <CGColor 0x156af0f0> [<CGColorSpace 0x15560350> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; Generic Gray Gamma 2.2 Profile; extended range)] ( 1 1 )>, 

<CALayer:0x15547290; position = CGPoint (59.5 23); bounds = CGRect (0 0; 2 2); delegate = <UIView: 0x155471b0; frame = (58.5 22; 2 2); 
layer = <CALayer: 0x15547290>>; allowsGroupOpacity = YES;
backgroundColor = <CGColor 0x156af0f0> [<CGColorSpace 0x15560350> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; Generic Gray Gamma 2.2 Profile; extended range)] ( 1 1 )>])

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+3

XXXButton.layer.insertSublayer(gradientLayer, at: 0)

これは、XXXButton.layerにSublayerを追加。

XXXButton.layer.removeFromSuperlayer()

これは、XXXButton.layerをSuperlayerから取り除く。


やりたいことは「XXXButton.layerのSublayer」をSuperlayer(== XXXButton.layer)から取り除く。

if let layer = button.layer.sublayers?.first { //button.layerの最初のSublayerを
    layer.removeFromSuperlayer() //Superlayerから取り除く
}

他にSublayerを追加していないのであれば、

button.layer.sublayers = nil

でいいような気も。

※動作未確認

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/13 16:49

    回答ありがとうございます。
    storyBoard上で背景をグラデーションで塗っているので、ご指摘の「他にSublayerを追加していないのであれば、」に該当して動かないようです。
    頂いたアドバイスをちょっといじって解決したいと思います。

    キャンセル

  • 2018/03/13 16:54

    それはnilを代入するときの話で、上側の書き方であれば問題ないと思うのですが。

    removeの直前に、
    print(button.layer.sublayers)
    を追加して、Sublayerを確認してみて下さい。

    キャンセル

  • 2018/03/13 16:59

    上側の書き方を試していたのですが、if let文のなかを通ったのでremoveFromSuperlayer()を
    実行したと思うのですが、自分の環境では対象レイヤーはfirstで捕まえられなかったようです。

    print(button.layer.sublayers)で確認してみます。

    キャンセル

  • 2018/03/13 17:11

    そのボタンはカスタムクラスを使っているのでしょうか?

    キャンセル

  • 2018/03/13 17:31 編集

    はい、カスタムクラスを作って、storyBoard上で割り当てています。
    カスタムクラス内でCAGradientLayerをつかっていることをすっかり忘れていました。
    print(button.layer.sublayers)ためしたところ、多量のレイヤーがあるようなかんじです。
    結果は、質問の一番下に貼ってみます。お時間がありましたら見てください。

    一歩後退してシンプルなテストプロジェクトをつくって試してみようと思います。

    キャンセル

  • 2018/03/13 17:52 編集

    2番目のやつですね。
    button.layer.sublayers?.first の代わりに button.layer.sublayers?[1] で、とりあえずいけると
    思いますが、さすがにそれはダメなので、作ったCAGradientLayerを保存しておいて、そのSublayerを取り除くような処理にするのがいいと思います。(追記:miyabi_takatsukさんの回答を参照)

    キャンセル

  • 2018/03/13 17:58 編集

    button.layer.sublayers?[1] で消えました。

    いろいろ本当にありがとうございます。
    firstで捕まえられないことといい、CALayerとサブクラスとなるCAGradientLayerで何か違いがあるのでしょうか?などなどじっくり調べて、頂いだ助言も合わせて解決してみたいと思います。

    キャンセル

  • 2018/03/13 18:18

    changeSelectedButtonBackgroundでCAGradientLayerを追加した後、他のどこかで(おそらくカスタムクラスの中で)Sublayerを追加しているからでしょう。

    キャンセル

  • 2018/03/13 18:39

    button.layer.sublayers?.firstは一番上のCAGradientLayerを取得
    button.layer.sublayers?.lastは一番下のCALayerを取得

    button.layer.sublayers?[1]はCALayerの中で一番上を取得?

    sublayersリスト



    1:CAGradientLayer ←firstで取得  
    2:CAGradientLayer
    3:CALayer : alpha = 0.2   ←[1]で取得  (1:のCAGradientLayer の親?)
    4:CALayer(UILabel?): alpha = 0.2      (2:のCAGradientLayer の親?)
    .
    .
    .
    .
    CALayer(UILabel?): alpha = 0.2 ←lastで取得



    CAGradientLayer は単体で削除できなくて、親を削除する?と消える?ってことですか?

    「CAGradientLayer を除いたfirst」で親?が取得できるかな?

    キャンセル

  • 2018/03/13 19:09 編集

    [1]は2番目です。
    first = [0] = 1番目です。

    CAGradientLayerとかCALayerとかは関係ありません。

    キャンセル

  • 2018/03/13 19:48

    すいません、インデックスですよね。勘違いしました。

    キャンセル

checkベストアンサー

+1

多分、ボタン自体の親からみて、ボタン自体のレイヤーを削除!ってなっちゃってるんだと思います。
gradientLayerを外で定義して、
削除するのはいかがでしょうか。
動作確認していないので、動かなかったら申し訳ないです・・・。

import UIKit

class ViewController: UIViewController {
  let gradientLayer: CALayer?
  let XXXButton: UIButton = UIButton()
  override func viewDidLoad() {
    super.viewDidLoad()

    // 各変数の設定は省略します。
    // gradientLayer = CALayer()とかで定義する
    self.XXXButton.layer.insertSublayer(gradientLayer!, at: 0)

    // 様々処理

    self.gradientLayer!.removeFromSuperlayer()
  }

}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/13 20:24

    「コメントする」ボタンを押し忘れてコメントが消えてしまっていたようです。
    最初に回答していただいてありがとうございました。

    外で定義して削除を試してみたいと思います。

    キャンセル

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

  • ただいまの回答率 90.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Swift

    7678questions

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