2017-01-06 3 views
1

この問題の説明の後にコードが続きます。0〜2枚の画像を持つUITableViewCellの高さを変更するための制約を設定するにはどうすればよいですか?

私はUITableViewを含むUIViewControllerを持っていますが、UITableViewCellの画像は1枚、2枚、または0枚の画像のいずれかを示しています。 1枚と2枚の画像では、セルの高さは常に72ですが、画像がなければゼロにする必要があります。私はUIViewを2つ持っています。最初のセルにはUIImageViewが含まれ、2番目には2つ含まれています。私は、そのセルが1つか2つの画像を持っているかどうかによって、隠れているか関連するものを表示しています。セルに画像がない場合は、UIViewの両方が隠されていますが、それらはまだ設定されている制約の一部を形成していますので、結果のセルは72ピクセルの高さですが、

は私が高さ、サイズ変更可能なUITableViewCell年代を作成するための唯一の方法は、ストーリーボードに制約を設定し、レイアウトの問題が発生しますオンザフライプログラム的制約の値をいじりことであると言われています。 (なし成功して)、次のようなアドバイスのいずれかが真であるかどうか私にはわからないので、私は試してみました:

  1. が私ResizableImageCellで高さを制御私のUIViewNSLayoutConstraint年代に明示的な参照を設定します呼び出し、原因となるのはUnable to simultaneously satisfy constraintsです。そして

  2. ResizableImageCellコールで高さを制御すべてNSLayoutConstraint年代への明示的な参照を設定します。または

  3. UIViewの両方を追加して削除すると、テーブルをスクロールして指を画面から持ち上げた後にテーブルが上下に飛び出し始めるまで正常に動作します。

これはViewControllerを制御する、現在のコードです:

import UIKit 

class ViewController: UIViewController 
{ 
    @IBOutlet weak var tableView: UITableView! 

    let imageNames = [ "room", "street", "tree" ] 



    override func viewDidLoad() 
    { 
     super.viewDidLoad() 

     tableView.delegate = self 
     tableView.dataSource = self 
     tableView.rowHeight = UITableViewAutomaticDimension 
     tableView.estimatedRowHeight = 44.0 
    } 



    func getRandomInt (from start: Int, to end: Int) -> Int 
    { 
     return Int(arc4random_uniform(UInt32((end + 1) - start))) + start 
    } 
} 



extension ViewController: UITableViewDataSource 
{ 
    @available(iOS 2.0, *) 
    public func tableView (_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "ResizableImageCell") as! ResizableImageCell 
     let numImages = getRandomInt(from: 0, to: 2) 

     cell.view1.isHidden = numImages != 1 
     cell.view2.isHidden = numImages != 2 

     var rand = getRandomInt(from: 0, to: imageNames.count - 1) 

     switch numImages 
     { 
     case 1:  cell.image1.image = UIImage(named: imageNames[ rand ]) 
     case 2:  cell.image2.image = UIImage(named: imageNames[ rand ]) 
     default: () 
     } 

     guard numImages == 2 else { return cell } 

     rand = getRandomInt(from: 0, to: imageNames.count - 1) 

     cell.image3.image = UIImage(named: imageNames[ rand ]) 

     return cell 
    } 



    func tableView (_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    { 
     return 64 
    } 
} 

これは私のオーダーメイドResizableImageCellセル

import UIKit 

class ResizableImageCell: UITableViewCell 
{ 
    @IBOutlet weak var view1: UIView! 
    @IBOutlet weak var view2: UIView! 

    @IBOutlet weak var image1: UIImageView! 
    @IBOutlet weak var image2: UIImageView! 
    @IBOutlet weak var image3: UIImageView! 



    override func awakeFromNib() 
    { 
     super.awakeFromNib() 
    } 
} 

そして、ここでは、既存のスクリーンショットで制御する、現在のコードですストーリーボード:

screenshot of a storyboard from XCode

ありがとうございます。

答えて

1

heighForRow機能を使用して私のプロジェクトでこの問題を解決しました。 ViewControllerで

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 

    //Check if you have to display images or not 

    //return 75 or CGFloat.ulpOfOne 
} 

たぶん、あなたはあなたのlet numImages = getRandomInt(from: 0, to: 2)cellForRowAtIndexPath機能を作成して、配列内の64件の結果を格納する必要があり、このソリューションで。

EDIT:Josh Homannから 重要な注意:

高さ0を返さないか、RECTが縮重しているので、あなたがコンソールでのいくつかの自動レイアウトエラーが出ることがあります。無限に小さいがゼロではないCGFloat.ulpOfOneを返します。

+0

ありがとうございます@チーフ - ルッツ、私はこれを試し、結果を知ってみましょう。 –

+0

だから@ Chief-Lutz:まだ決定的なものはないが、あなたの提案がうまくいくように見える。ありがとう。 –

+0

@ TheMotherofJosephBeuys - それが助けてくれることを願っています。あなたは大歓迎です:) –

0

は(すぐ上で概説)チーフ・ルッツのheightForRowAt提案@使用してこの問題を解決したので、私は、その後も同様に動作します別の解決策があることに気づきました。 heightForRowAtの内部で高さ計算を実行する代わりに、それぞれが異なる数の画像に対応するように設計された複数のペン先を持つことが可能です。これは、高さの計算がボンネットの下で行われるため、コードが簡単で短くなります。下側にはおそらくいくつかの繰り返しレイアウトや制約がある複数のペン先があります。 sおよびそれらを移入「は、この場合にheightForRowAtに必要な計算の一部がUILabel細胞を作成し、[再]を含むので、S」の

このアプローチは、あなたの細胞が1つまたは複数のゼロラインUILabelが含まれている場合に特に有用であることが判明しますテキストが表示されるので、レンダリング時に各セルがどれくらい高く表示されるかをサイズ変更して通知することができます。の前にcellForRowAtと呼びます。

関連する問題