ThumbView
This option allows you to display our custom widget that display stories in an horizontal collectionView with an Instagram-like UI.
Layout
By subclasssing StoryTransitionViewController
When working with custom widget, we are able to apply custom transition between stories collectionView (thumbnails) cells and stories player. To achieve this, you then need to inherits from a class called StoryTransitionViewController
Because you'll have an inherited CollectionView to display Thumbnails, you will need to implement methods from UICollectionViewDelegateFlowLayout
and UICollectionViewDataSource
(but UICollectionViewDelegate
already being implemented by the parent class)
UICollectionViewDelegateFlowLayout
should be implemented to matchStoryViewConfig
parameters.
public func collectionView(_: collectionViewLayout: sizeForItemAt:)
public func collectionView(_: collectionViewLayout: minimumLineSpacingForSectionAt:) -> CGFloat
- Inside
viewDidLoad
, add viewController as dataSource of your collectionView
collectionView.dataSource = self
- You also need to set the JoinStoriesThumbConfig instance you created
let config = JoinStoriesThumbConfig(...)
self.config = config
- For
UICollectionViewDataSource
, implementnumberOfItemsInSection
andfunc collectionView(_:, cellForItemAt:)
Without subclasssing StoryTransitionViewController
- Create your custom ViewController and add protocol conformance with CollectionView
class YourViewController: StoryTransitionViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
- Add
var stories: [StoryValue] = []
variable for stories loading - Add
collectionView
variable and registerStoryCollectionViewCell
lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.translatesAutoresizingMaskIntoConstraints = false
cv.showsHorizontalScrollIndicator = false
cv.showsVerticalScrollIndicator = false
cv.register(StoryCollectionViewCell.self, forCellWithReuseIdentifier: StoryCollectionViewCell.reuseIdentifier)
return cv
}()
- Inside
viewDidLoad
, add viewController as delegate and datasource of your collectionView
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(collectionView)
// Add view controller as DataSource of `collectionView`
collectionView.dataSource = self
// Add view controller as Delegate of `collectionView`
collectionView.delegate = self
collectionView.backgroundColor = .black
collectionView.topAnchor.constraint(equalTo: view.topAnchor, constant: "your_top_anchor_constant") .isActive = true
}
- Implement
UICollectionViewDelegateFlowLayout
methods to match storyViewConfig parameters.
public func collectionView(_: collectionViewLayout: sizeForItemAt:)
public func collectionView(_: collectionViewLayout: minimumLineSpacingForSectionAt:) -> CGFloat
Implement
UICollectionViewDataSource
methods to providenumberOfItemsInSection
andfunc collectionView(_:, cellForItemAt:)
Implement
UICollectionViewDelegate
methods to present StoryPlayer by calling custompresentStoryPlayer(stories:beginningAt:animated:)
public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
presentStoryPlayer(stories: stories, beginningAt: indexPath, animated: true)
}
- Conforms to
StoryNavigationDelegate
and implement markAsSeen fonctionnality
public func storyItemShown(at indexPath: IndexPath) {
guard let cell = collectionView.cellForItem(at: indexPath) as? StoryCollectionViewCell else {
return
}
let storyAtIndex = stories[indexPath.row]
cell.storyPersistence.markAsSeen(id: storyAtIndex.id)
collectionView.reloadItems(at: [indexPath])
}
Trigger
To start the display of our thumbView widget, you need to call (in viewDidLoad
for example):
JoinStories.startThumbView(config: "your_thumbView_config") { [weak self] result in
switch result {
case .success(let stories):
// Assign stories from result (Result<[StoryValue], StoriesAPIError>)
self?.stories = stories
// Refresh your view on the main thread
DispatchQueue.main.async {
// self?.collectionView.reloadData()
}
case .failure(let error):
// Handle error (by displaying a message for instance)
...
}
}
If you want to refresh stories when we came from background, you can add an observer inside viewDidLoad
method as follow
NotificationCenter.default.addObserver(self, selector: #selector(_your_method_name), name: UIApplication.willEnterForegroundNotification, object: nil)
Configuration
You can fine tune SDK behavior and UI, by specifying optional values on JoinStoriesThumbConfig.
Available configuration parameters:
Name | Type | Default Value | Description |
---|---|---|---|
alias | String | YES | The Join Stories alias you were given to configure your integration |
requestTimeoutInterval | TimeInterval | 60 | Timeout used for the stories fetching network requests (call and read) |
fontName | String | HelveticaNeue-Bold | Thumb views label custom font (withLabel should be true) |
labelColor | UIColor | UIColor.black | Thumb views label custom text color (withLabel should be true) |
thumbViewSpacing | Int | 32 | Spacing between thumb views |
withLabel | Bool | true | Show/hide text below each thumb view |
loaderInnerViewWidth | Int | 8 | Spacing between the image and the loader in a thumb view |
loaderInnerViewColor | [UIColor] | [UIColor.black] | Color between the image and the loader in a thumb view |
loaderColors | [UIColor] | [UIColor.red, UIColor.blue] | Colors of the thumb view loader. A sweep gradient will be applied on it |
loaderWidth | Int | 8 | Width of the thumb view loader |
storyViewedIndicatorColor | UIColor | UIColor.gray | Color of the thumb view indicator displayed when a story has been viewed by the user |
storyViewedIndicatorAlpha | Float | 0.8 | Alpha of the thumb view indicator displayed when a story has been viewed by the user. Range [0..1] |
thumbViewOverlayColor | UIColor | UIColor(hex8: 0x4C4C4CBB) | Color of the overlay displayed on the thumb view image when a story was selected by the user and is loading |
playerBackgroundColor | UIColor | UIColor.black | Color of the player's background, if the player height is smaller than screen dimensions |
playerVerticalAnchor | PlayerVerticalAnchor | .bottom | If the player's height is smaller than screen height, anchor it to the top or bottom of the screen |
playerShowShareButton | Boolean | true | Change the visibility of the share button displayed on the Player view |
playerClosingButton | Boolean | true | Change the visibility of the close button displayed on the Player view |
playerHorizontalMargins | Int | 0 | Apply the margin to the left and right of the player view. To maintain ratio, it also changes the height of the player view. |
playerCornerRadius | Int | 0 | Apply radius to the 4 corners of the player view |
playerProgressBarDefaultColor | String? | nil | Change the background color of the progress bar in the player view. If no value or nil is filled, the default color will be used. Format is ##RRGGBB or #RRGGBBAA |
playerProgressBarFillColor | String? | nil | Change the fill color of the progress bar in the player view. If no value or nil is filled, the default color will be used. Format is ##RRGGBB or #RRGGBBAA |
playerProgressBarThickness | Int? | nil | Change the thickness of the progress bar in the player view. If no value or nil is filled, the default thickness will be used. |
playerProgressBarRadius | Int? | nil | Change the radius of the progress bar in the player view. If no value or nil is filled, the default thickness will be used. Radius will be applied to the 4 corners. |
Multiple widgets
You can implement our thumbView widget multiple times on the same screen, with the same or different join_alias.
To do so, you just need to call the startThumbView method n
times.