So I need a bit of help since I can't really figure it out and have spent a lot of time on it already without any results. Most of the things I find on the internet are on how to convert a swift project into a framework, but my issue isn't the project itself or cocoapods, it's about how and what I should make accessible to developers.
So I built a Swift framework which you can find here, it's built with a UICollectionView
with a custom flowlayout
and side swiping functionality.
The problem is that I don't know how I can make this easy to use for developers, I'd like to make it behave like a UICollectionView
where you'd need to implement a custom delegate and datasource without having to use the default UICollectionViewDelegate
and UICollectionViewDatasource
, so I can filter out things that would cause unexpected behaviour or just keep things simple.
So what would be a good approach here? I'm thinking about possibly subclassing the UICollectionView
so people don't have to use a UICollectionView
(because that might get confusing) but a VerticalCardSwiperView
instead which has the same behaviour, but a bit more limited. I just don't know if that's the correct approach here.
Any tips, insights or good examples would be deeply appreciated!
edit 1: I updated the project so it already has the framework structure, I just need to figure out how I'm going to give access to the custom parts to developers.
edit 2: I have gotten one answer but I think the question might be easily misunderstood. The goal is to make it act and behave like a UICollectionView
(with delegates, datasource, ...) but more limited, and I'm wondering how I can accomplish that, if it's even possible.
edit 3: Alright, I have most of it working, I'll leave a link to the Github online here so people who need something similar can check it out for themselves. Essentially, what I've done is made a custom VerticalCardSwiperDelegate
and VerticalCardSwiperDatasource
like this:
/// This datasource is used for providing data to the `VerticalCardSwiper`.
public protocol VerticalCardSwiperDatasource: class {
/**
Sets the number of cards for the `UICollectionView` inside the VerticalCardSwiperController.
- parameter verticalCardSwiperView: The `VerticalCardSwiperView` where we set the amount of cards.
- returns: an `Int` with the amount of cards we want to show.
*/
func numberOfCards(verticalCardSwiperView: VerticalCardSwiperView) -> Int
/**
Asks your data source object for the cell that corresponds to the specified item in the `VerticalCardSwiper`.
Your implementation of this method is responsible for creating, configuring, and returning the appropriate `CardCell` for the given item.
- parameter verticalCardSwiperView: The `VerticalCardSwiperView` that will display the `CardCell`.
- parameter index: The that the `CardCell` should be shown at.
- returns: A CardCell object. The default value is an empty CardCell object.
*/
func cardForItemAt(verticalCardSwiperView: VerticalCardSwiperView, cardForItemAt index: Int) -> CardCell
}
and then I've hooked those up inside the VerticalCardSwiper
class:
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return datasource?.numberOfCards(verticalCardSwiperView: verticalCardSwiperView) ?? 0
}
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
return (datasource?.cardForItemAt(verticalCardSwiperView: verticalCardSwiperView, cardForItemAt: indexPath.row))!
}
And lastly, I've just subclassed the UICollectionView
to a VerticalCardSwiperView
and passed that as a paramater (since it's basically a subclass of the UICollectionView
it does the same things, just has a different name, which is easier to understand for developers) for the delegate/datasource functions. Hope this helps someone else. Also, if you have a better approach, please let me know.
It looks great!
I'd say that if you want to expose UICollectionView
then follow the UITableView
and it's approach with the UIScrollView
subclassed delegates.
protocol VerticalCardSwiperDelegate: UICollectionViewDelegate {
// ...
You can also subclass UICollectionViewDelegate
and UICollectionViewDataSource
in VerticalCardSwiperDelegate
and VerticalCardSwiperDataSource
delegates, respectively, for the same effect. (If you think it makes sense to do so.)
protocol VerticalCardSwiperDelegate: UICollectionViewDelegate {
// ...
That said, your component is quite specific and maybe exposing the underlying UICollectionView could cause problems. Here, I'd lock all the implementation details away and make it VerticalCardSwiper
all the way. This affords you the flexibility to complete change the underlying architecture.
For example, in your delegates, you would pass back VerticalCardSwiper
rather than the underlying component..
func cardForItemAt(verticalCardSwiper: VerticalCardSwiper, cardForItemAt index: Int) -> CardCell {
// ...
Generally, you want to keep the exposed interface as small as possible. This is to help guide the developers (there is less to learn) and less for you to maintain and field questions.
Some comments on the public interfaces would be helpful. I'm happy when I can command-alt-click to get some hints. You've already done this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With