LoginSignup
KAinone
@KAinone

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

UICollectionViewクラスをUIViewControllerにaddSubviewする

Q&AClosed

解決したいこと

タイトル通り、UICollectionViewクラスをUIViewControllerにaddSubviewしたいのですが、以下のインスタンスの生成方法だと上手くいきませんでした。
他に方法があれば教えてください。よろしくお願いします。

該当するソースコード

<UICollectionViewクラス>

class CarouselView: UICollectionView, UICollectionViewDelegate, UICollectionViewDataSource {
//略
}

発生している問題・エラー

var carouselView: CarouselView! の場合>

class HomeViewController: UIViewController {

    var carouselView: CarouselView!

    override func viewDidLoad() {
        
        super.viewDidLoad()
        
        setupSubviews()
    }

    func setupSubviews() {
    
        self.view.addSubview(carouselView) //nilでエラー

        //略
    }

}

以下のエラーが出て落ちました。

Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

let carouselView = CarouselView() の場合>

class HomeViewController: UIViewController {

    let carouselView = CarouselView()

    override func viewDidLoad() {
        
        super.viewDidLoad()
        
        setupSubviews()
    }

    func setupSubviews() {
    
        self.view.addSubview(carouselView)

        carouselView.snp.makeConstraints {
            
            $0.width.equalToSuperview()
            $0.height.equalTo(view.frame.size.width)
            $0.top.equalTo(headerLabel.snp.bottom).offset(40)
        }

        //略
    }

}

エラーは出ませんが以下のようにレイアウトがおかしくなります。白いViewがCarouselViewですが、左半分くらいの大きさにしか表示されません。(インスタンスとは関係ないかも?)Screenshot 2023-11-21 at 7.43.50.png

*HomeViewControllerはTabBarControllerで表示しています。

0

1Answer

以下のエラーが出て落ちました。

carouselView変数は型の宣言だけで、だれもインスタンスをセットしていないなら、nilで落ちるのは必然ですね。


エラーは出ませんが以下のようにレイアウトがおかしくなります。白いViewがCarouselViewですが、左半分くらいの大きさにしか表示されません。

指定した制約(レイアウト)が、そういう内容だったということですが、

$0.width.equalToSuperview()
$0.height.equalTo(view.frame.size.width)
$0.top.equalTo(headerLabel.snp.bottom).offset(40)
  • widthに指定したequalToSuperview()が横幅として意図したサイズになっているのか、ここが一番怪しい気がします。
  • heightに親Viewのwidthを指定しているのは、意図的でしょうか。
  • headerLabelがコード上存在しないので、それがどういったレイアウトになっているか分かりかねます。

なお、GitHub上のコードを確認しましたが、上のコードとは全然違いましたので、動作させての確認はしていません。

1

Comments

  1. @KAinone

    Questioner

    ご回答いただきありがとうございます。

    なお、GitHub上のコードを確認しましたが、上のコードとは全然違いましたので、動作させての確認はしていません。

    HomeViewControllerからtableViewをなくしCellも削除してcollectionView(CarouselView)を直接レイアウトしようと思い、その修正途中だったのでGitHubではまだ更新していませんでした。
    親がviewだと思ったので、heightにwidthと同じサイズを指定して正方形にしたかったのですが、そもそもwidth.equalToSuperview()が何故か意図したサイズになっていませんでした。
    思いの外手こずったのと、解決方法を教えていただいたので、元のtableViewに戻しました。
    GitHubは現在更新済みです。

    carouselView変数は型の宣言だけで、だれもインスタンスをセットしていないなら、nilで落ちるのは必然ですね。

    おっしゃる通り、何もセットしていませんでしたので、frameを入れてからaddSubviewしました。そうすると表示はされますが、contentViewに収まらないレイアウトになってしまったので、二重に制約をしていいのかわかりませんが、後からsnpでレイアウトしたらちゃんと表示されました。

    let width = contentView.frame.width
    let height = contentView.frame.height
    
    carouselView = CarouselView(frame: CGRect(x: 0, y: 0, width: width, height: width))
    carouselView.center = CGPoint(x: width / 2, y: height / 2)
    
    contentView.addSubview(carouselView)
    
    carouselView.snp.makeConstraints {
        
        $0.top.equalToSuperview().offset(50)
        $0.leading.equalToSuperview()
        $0.trailing.equalToSuperview()
        $0.bottom.equalToSuperview()
    }
    

Your answer might help someone💌