I am trying to add three buttons above a collection view that pulls either the videos, photos, or all content from the photo library based on what button a user selects.
I managed to create the collection view and the buttons separately but when I try to combine them in a vertical stack view I get an error where I declare the UIStackView.
I am trying to combine a horizontal stack view (the buttons) into a vertical stack view (the button stack view on top and the collection view below).
I think the error is related to how I am declaring the buttonStack but everything I have tried has failed.
I assumed that two stacked views would be the best way to accomplish my goal but I am open to other/better suggestions. Regardless I would like to know why this is not working for me.
Code line and error message:
let stackView = UIStackView(arrangedSubviews: [buttonsStack, collectionView!])
Type of expression is ambiguous without more context
class TestVideoItemCell: UICollectionViewCell {
var stackView = UIStackView()
var vid = UIImageView()
override init(frame: CGRect) {
super.init(frame: frame)
vid.contentMode = .scaleAspectFill
vid.clipsToBounds = true
self.addSubview(vid)
}
override func layoutSubviews() {
super.layoutSubviews()
vid.frame = self.bounds
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class TestVideoViewVC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UINavigationControllerDelegate {
var myCollectionView: UICollectionView!
var videoArray = [UIImage]()
override func viewDidLoad() {
super.viewDidLoad()
grabVideos()
}
//MARK: CollectionView
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return videoArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "videoCell", for: indexPath) as! VideoItemCell
cell.vid.image = videoArray[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.frame.width
return CGSize(width: width/4 - 1, height: width/4 - 1)
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
myCollectionView.collectionViewLayout.invalidateLayout()
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 1.0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 1.0
}
//MARK: grab videos
func grabVideos(){
videoArray = []
DispatchQueue.global(qos: .background).async {
let imgManager = PHImageManager.default()
let requestOptions = PHImageRequestOptions()
requestOptions.isSynchronous = true
requestOptions.deliveryMode = .highQualityFormat
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key:"creationDate", ascending: false)]
let fetchResult: PHFetchResult = PHAsset.fetchAssets(with: .video, options: fetchOptions)
print(fetchResult)
print(fetchResult.count)
if fetchResult.count > 0 {
for i in 0..<fetchResult.count{
imgManager.requestImage(for: fetchResult.object(at: i) as PHAsset, targetSize: CGSize(width:500, height: 500),contentMode: .aspectFill, options: requestOptions, resultHandler: { (image, error) in
self.videoArray.append(image!)
})
}
} else {
print("No videos found.")
}
DispatchQueue.main.async {
self.myCollectionView.reloadData()
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: SetUp Methods
func buttonsStack() {
let buttonChoices = ButtonStackView()
buttonChoices.setupButtonsStackView()
}
func setupCollection() {
let layout = UICollectionViewFlowLayout()
myCollectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
myCollectionView.delegate = self
myCollectionView.dataSource = self
myCollectionView.register(VideoItemCell.self, forCellWithReuseIdentifier: "videoCell")
myCollectionView.backgroundColor = UIColor.white
self.view.addSubview(myCollectionView)
myCollectionView.autoresizingMask = UIView.AutoresizingMask(rawValue: UIView.AutoresizingMask.RawValue(UInt8(UIView.AutoresizingMask.flexibleWidth.rawValue) | UInt8(UIView.AutoresizingMask.flexibleHeight.rawValue)))
}
func setupStack() {
let stackView = UIStackView(arrangedSubviews: [buttonsStack, collectionView!])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.distribution = .fillEqually
stackView.axis = .horizontal
stackView.spacing = 8
view.addSubview(stackView)
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
stackView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
])
}
}
UPDATE
Below is an image example of the general concept of the UI I am trying to create.