Toggle navigation
Toggle navigation
This project
Loading...
Sign in
open-source
/
warply_sdk_framework
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Graphs
Network
Create a new issue
Commits
Issue Boards
Authored by
Manos Chorianopoulos
2026-03-20 10:34:44 +0200
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
03fbadc9787068fefb81ff1e596fa490ef596479
03fbadc9
1 parent
7428843e
CategoryOffers part2
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
390 additions
and
107 deletions
SwiftWarplyFramework/SwiftWarplyFramework.xcworkspace/xcuserdata/manoschorianopoulos.xcuserdatad/UserInterfaceState.xcuserstate
SwiftWarplyFramework/SwiftWarplyFramework/cells/CategoryOfferCollectionViewCell/CategoryOfferCollectionViewCell.swift
SwiftWarplyFramework/SwiftWarplyFramework/cells/CategoryOfferCollectionViewCell/CategoryOfferCollectionViewCell.xib
SwiftWarplyFramework/SwiftWarplyFramework/cells/CategoryOffersGridTableViewCell/CategoryOffersGridTableViewCell.swift
SwiftWarplyFramework/SwiftWarplyFramework/cells/MyRewardsOffersScrollTableViewCell/MyRewardsOffersScrollTableViewCell.swift
SwiftWarplyFramework/SwiftWarplyFramework/screens/CategoryOffersViewController/CategoryOffersViewController.swift
SwiftWarplyFramework/SwiftWarplyFramework/screens/MyRewardsViewController/MyRewardsViewController.swift
SwiftWarplyFramework/SwiftWarplyFramework/screens/ProfileViewController/ProfileViewController.swift
SwiftWarplyFramework/SwiftWarplyFramework.xcworkspace/xcuserdata/manoschorianopoulos.xcuserdatad/UserInterfaceState.xcuserstate
View file @
03fbadc
No preview for this file type
SwiftWarplyFramework/SwiftWarplyFramework/cells/CategoryOfferCollectionViewCell/CategoryOfferCollectionViewCell.swift
View file @
03fbadc
...
...
@@ -9,10 +9,118 @@ import UIKit
@objc(CategoryOfferCollectionViewCell)
public
class
CategoryOfferCollectionViewCell
:
UICollectionViewCell
{
@IBOutlet
weak
var
parentView
:
UIView
!
@IBOutlet
weak
var
bannerImage
:
UIImageView
!
@IBOutlet
weak
var
logoImage
:
UIImageView
!
@IBOutlet
weak
var
discountView
:
UIView
!
@IBOutlet
weak
var
discountLabel
:
UILabel
!
@IBOutlet
weak
var
merchantNameLabel
:
UILabel
!
@IBOutlet
weak
var
titleLabel
:
UILabel
!
@IBOutlet
weak
var
subtitleLabel
:
UILabel
!
@IBOutlet
weak
var
expirationLabel
:
UILabel
!
var
postImageURL
:
String
?
{
didSet
{
if
let
url
=
postImageURL
{
self
.
bannerImage
.
image
=
UIImage
()
UIImage
.
loadImageUsingCacheWithUrlString
(
url
)
{
image
in
if
url
==
self
.
postImageURL
{
self
.
bannerImage
.
image
=
image
}
}
}
else
{
self
.
bannerImage
.
image
=
nil
}
}
}
var
logoImageURL
:
String
?
{
didSet
{
if
let
url
=
logoImageURL
{
self
.
logoImage
.
image
=
UIImage
()
UIImage
.
loadImageUsingCacheWithUrlString
(
url
)
{
image
in
if
url
==
self
.
logoImageURL
{
self
.
logoImage
.
image
=
image
}
}
}
else
{
self
.
logoImage
.
image
=
nil
}
}
}
public
override
func
awakeFromNib
()
{
super
.
awakeFromNib
()
// Initialization code
parentView
.
layer
.
borderWidth
=
1.0
parentView
.
layer
.
borderColor
=
UIColor
(
rgb
:
0xD2D6D9
)
.
cgColor
parentView
.
layer
.
cornerRadius
=
12.0
parentView
.
clipsToBounds
=
true
logoImage
.
layer
.
cornerRadius
=
8.0
logoImage
.
clipsToBounds
=
true
logoImage
.
backgroundColor
=
UIColor
(
rgb
:
0xEEEEEE
)
discountView
.
layer
.
cornerRadius
=
17.0
discountView
.
clipsToBounds
=
true
}
func
configureCell
(
data
:
OfferModel
)
{
bannerImage
.
image
=
UIImage
(
named
:
data
.
bannerImage
,
in
:
Bundle
.
frameworkResourceBundle
,
compatibleWith
:
nil
)
discountLabel
.
text
=
data
.
discount
discountLabel
.
font
=
UIFont
(
name
:
"PingLCG-Bold"
,
size
:
14
)
discountLabel
.
textColor
=
UIColor
(
rgb
:
0xFFFFFF
)
discountView
.
backgroundColor
=
UIColor
(
rgb
:
0xCBCBCB
)
merchantNameLabel
.
text
=
data
.
title
merchantNameLabel
.
font
=
UIFont
(
name
:
"PingLCG-Regular"
,
size
:
12
)
merchantNameLabel
.
textColor
=
UIColor
(
rgb
:
0x000F1E
)
titleLabel
.
text
=
data
.
title
titleLabel
.
font
=
UIFont
(
name
:
"PingLCG-Bold"
,
size
:
15
)
titleLabel
.
textColor
=
UIColor
(
rgb
:
0x000F1E
)
subtitleLabel
.
text
=
data
.
description
subtitleLabel
.
font
=
UIFont
(
name
:
"PingLCG-Regular"
,
size
:
13
)
subtitleLabel
.
textColor
=
UIColor
(
rgb
:
0x00111B
)
expirationLabel
.
text
=
data
.
expirationDate
expirationLabel
.
font
=
UIFont
(
name
:
"PingLCG-Regular"
,
size
:
12
)
expirationLabel
.
textColor
=
UIColor
(
rgb
:
0x9BA1A6
)
logoImage
.
image
=
UIImage
(
named
:
data
.
merchantLogo
,
in
:
Bundle
.
frameworkResourceBundle
,
compatibleWith
:
nil
)
}
func
configureCell
(
data
:
CouponSetItemModel
)
{
self
.
postImageURL
=
data
.
_app_img_preview
discountLabel
.
text
=
data
.
_discount
discountLabel
.
font
=
UIFont
(
name
:
"PingLCG-Bold"
,
size
:
14
)
discountLabel
.
textColor
=
UIColor
(
rgb
:
0xFFFFFF
)
discountView
.
backgroundColor
=
UIColor
(
rgb
:
0xCBCBCB
)
if
let
merchant
=
data
.
_merchant
{
merchantNameLabel
.
text
=
merchant
.
_admin_name
self
.
logoImageURL
=
merchant
.
_img_preview
}
else
{
merchantNameLabel
.
text
=
""
self
.
logoImageURL
=
nil
}
merchantNameLabel
.
font
=
UIFont
(
name
:
"PingLCG-Regular"
,
size
:
12
)
merchantNameLabel
.
textColor
=
UIColor
(
rgb
:
0x000F1E
)
titleLabel
.
text
=
data
.
_name
titleLabel
.
font
=
UIFont
(
name
:
"PingLCG-Bold"
,
size
:
15
)
titleLabel
.
textColor
=
UIColor
(
rgb
:
0x000F1E
)
subtitleLabel
.
text
=
data
.
_short_description
subtitleLabel
.
font
=
UIFont
(
name
:
"PingLCG-Regular"
,
size
:
13
)
subtitleLabel
.
textColor
=
UIColor
(
rgb
:
0x00111B
)
expirationLabel
.
text
=
"until "
+
data
.
formattedEndDate
(
format
:
"dd-MM"
)
expirationLabel
.
font
=
UIFont
(
name
:
"PingLCG-Regular"
,
size
:
12
)
expirationLabel
.
textColor
=
UIColor
(
rgb
:
0x9BA1A6
)
}
}
...
...
SwiftWarplyFramework/SwiftWarplyFramework/cells/CategoryOfferCollectionViewCell/CategoryOfferCollectionViewCell.xib
View file @
03fbadc
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document
type=
"com.apple.InterfaceBuilder3.CocoaTouch.XIB"
version=
"3.0"
toolsVersion=
"13142"
targetRuntime=
"iOS.CocoaTouch"
propertyAccessControl=
"none"
useAutolayout=
"YES"
useTraitCollections=
"YES"
useSafeAreas=
"YES"
colorMatched=
"YES"
>
<?xml version="1.0" encoding="UTF-8"?>
<document
type=
"com.apple.InterfaceBuilder3.CocoaTouch.XIB"
version=
"3.0"
toolsVersion=
"24506"
targetRuntime=
"iOS.CocoaTouch"
propertyAccessControl=
"none"
useAutolayout=
"YES"
useTraitCollections=
"YES"
useSafeAreas=
"YES"
colorMatched=
"YES"
>
<device
id=
"retina6_12"
orientation=
"portrait"
appearance=
"light"
/>
<dependencies>
<plugIn
identifier=
"com.apple.InterfaceBuilder.IBCocoaTouchPlugin"
version=
"
12042
"
/>
<plugIn
identifier=
"com.apple.InterfaceBuilder.IBCocoaTouchPlugin"
version=
"
24504
"
/>
<capability
name=
"Safe area layout guides"
minToolsVersion=
"9.0"
/>
<capability
name=
"System colors in document resources"
minToolsVersion=
"11.0"
/>
<capability
name=
"documents saved in the Xcode 8 format"
minToolsVersion=
"8.0"
/>
</dependencies>
<objects>
<placeholder
placeholderIdentifier=
"IBFilesOwner"
id=
"-1"
userLabel=
"File's Owner"
/>
<placeholder
placeholderIdentifier=
"IBFirstResponder"
id=
"-2"
customClass=
"UIResponder"
/>
<collectionViewCell
opaque=
"NO"
clipsSubviews=
"YES"
multipleTouchEnabled=
"YES"
contentMode=
"center"
id=
"gTV-IL-0wX"
customClass=
"CategoryOfferCollectionViewCell"
customModuleProvider=
"target"
>
<rect
key=
"frame"
x=
"0.0"
y=
"0.0"
width=
"
50"
height=
"5
0"
/>
<collectionViewCell
opaque=
"NO"
clipsSubviews=
"YES"
multipleTouchEnabled=
"YES"
contentMode=
"center"
id=
"gTV-IL-0wX"
customClass=
"CategoryOfferCollectionViewCell"
customModule
=
"SwiftWarplyFramework"
customModule
Provider=
"target"
>
<rect
key=
"frame"
x=
"0.0"
y=
"0.0"
width=
"
170"
height=
"28
0"
/>
<autoresizingMask
key=
"autoresizingMask"
/>
<view
key=
"contentView"
opaque=
"NO"
clipsSubviews=
"YES"
multipleTouchEnabled=
"YES"
contentMode=
"center"
>
<rect
key=
"frame"
x=
"0.0"
y=
"0.0"
width=
"50"
height=
"50"
/>
<color
key=
"backgroundColor"
red=
"0.0"
green=
"0.0"
blue=
"0.0"
alpha=
"0.0"
colorSpace=
"custom"
customColorSpace=
"sRGB"
/>
<rect
key=
"frame"
x=
"0.0"
y=
"0.0"
width=
"170"
height=
"280"
/>
<autoresizingMask
key=
"autoresizingMask"
flexibleMaxX=
"YES"
flexibleMaxY=
"YES"
/>
<subviews>
<!-- parentView: card container with border + rounded corners -->
<view
contentMode=
"scaleToFill"
translatesAutoresizingMaskIntoConstraints=
"NO"
id=
"A1B-CD-EFG"
userLabel=
"parentView"
>
<rect
key=
"frame"
x=
"0.0"
y=
"0.0"
width=
"170"
height=
"280"
/>
<subviews>
<!-- Top View: gray background, banner image, logo, discount -->
<view
contentMode=
"scaleToFill"
translatesAutoresizingMaskIntoConstraints=
"NO"
id=
"TOP-vw-001"
userLabel=
"TopView"
>
<rect
key=
"frame"
x=
"0.0"
y=
"0.0"
width=
"170"
height=
"140"
/>
<subviews>
<!-- Banner image fills the top view -->
<imageView
clipsSubviews=
"YES"
userInteractionEnabled=
"NO"
contentMode=
"scaleAspectFill"
horizontalHuggingPriority=
"251"
verticalHuggingPriority=
"251"
translatesAutoresizingMaskIntoConstraints=
"NO"
id=
"BNR-img-001"
>
<rect
key=
"frame"
x=
"0.0"
y=
"0.0"
width=
"170"
height=
"140"
/>
</imageView>
<!-- Logo image: centered in top view -->
<imageView
clipsSubviews=
"YES"
userInteractionEnabled=
"NO"
contentMode=
"scaleAspectFit"
horizontalHuggingPriority=
"251"
verticalHuggingPriority=
"251"
translatesAutoresizingMaskIntoConstraints=
"NO"
id=
"LGO-img-001"
>
<rect
key=
"frame"
x=
"51"
y=
"42"
width=
"48"
height=
"48"
/>
<constraints>
<constraint
firstAttribute=
"width"
constant=
"48"
id=
"LGO-w-001"
/>
<constraint
firstAttribute=
"height"
constant=
"48"
id=
"LGO-h-001"
/>
</constraints>
</imageView>
<!-- Discount circle: top-right -->
<view
contentMode=
"scaleToFill"
translatesAutoresizingMaskIntoConstraints=
"NO"
id=
"DSC-vw-001"
userLabel=
"discountView"
>
<rect
key=
"frame"
x=
"130"
y=
"8"
width=
"34"
height=
"34"
/>
<subviews>
<label
opaque=
"NO"
userInteractionEnabled=
"NO"
contentMode=
"center"
horizontalHuggingPriority=
"251"
verticalHuggingPriority=
"251"
text=
"%"
textAlignment=
"center"
lineBreakMode=
"middleTruncation"
baselineAdjustment=
"alignBaselines"
adjustsFontSizeToFit=
"YES"
minimumFontScaleFactor=
"0.5"
translatesAutoresizingMaskIntoConstraints=
"NO"
id=
"DSC-lbl-001"
>
<rect
key=
"frame"
x=
"2"
y=
"2"
width=
"30"
height=
"30"
/>
<fontDescription
key=
"fontDescription"
type=
"system"
pointSize=
"14"
/>
<nil
key=
"textColor"
/>
<nil
key=
"highlightedColor"
/>
</label>
</subviews>
<color
key=
"backgroundColor"
red=
"0.796"
green=
"0.796"
blue=
"0.796"
alpha=
"1"
colorSpace=
"custom"
customColorSpace=
"sRGB"
/>
<constraints>
<constraint
firstAttribute=
"width"
constant=
"34"
id=
"DSC-w-001"
/>
<constraint
firstAttribute=
"height"
constant=
"34"
id=
"DSC-h-001"
/>
<constraint
firstItem=
"DSC-lbl-001"
firstAttribute=
"top"
secondItem=
"DSC-vw-001"
secondAttribute=
"top"
constant=
"2"
id=
"DSC-t-001"
/>
<constraint
firstItem=
"DSC-lbl-001"
firstAttribute=
"leading"
secondItem=
"DSC-vw-001"
secondAttribute=
"leading"
constant=
"2"
id=
"DSC-l-001"
/>
<constraint
firstAttribute=
"trailing"
secondItem=
"DSC-lbl-001"
secondAttribute=
"trailing"
constant=
"2"
id=
"DSC-tr-001"
/>
<constraint
firstAttribute=
"bottom"
secondItem=
"DSC-lbl-001"
secondAttribute=
"bottom"
constant=
"2"
id=
"DSC-b-001"
/>
</constraints>
</view>
</subviews>
<color
key=
"backgroundColor"
red=
"0.937"
green=
"0.941"
blue=
"0.945"
alpha=
"1"
colorSpace=
"custom"
customColorSpace=
"sRGB"
/>
<constraints>
<!-- Banner fills top view -->
<constraint
firstItem=
"BNR-img-001"
firstAttribute=
"top"
secondItem=
"TOP-vw-001"
secondAttribute=
"top"
id=
"BNR-t-001"
/>
<constraint
firstItem=
"BNR-img-001"
firstAttribute=
"leading"
secondItem=
"TOP-vw-001"
secondAttribute=
"leading"
id=
"BNR-l-001"
/>
<constraint
firstAttribute=
"trailing"
secondItem=
"BNR-img-001"
secondAttribute=
"trailing"
id=
"BNR-tr-001"
/>
<constraint
firstAttribute=
"bottom"
secondItem=
"BNR-img-001"
secondAttribute=
"bottom"
id=
"BNR-b-001"
/>
<!-- Logo centered -->
<constraint
firstItem=
"LGO-img-001"
firstAttribute=
"centerX"
secondItem=
"TOP-vw-001"
secondAttribute=
"centerX"
id=
"LGO-cx-001"
/>
<constraint
firstItem=
"LGO-img-001"
firstAttribute=
"centerY"
secondItem=
"TOP-vw-001"
secondAttribute=
"centerY"
id=
"LGO-cy-001"
/>
<!-- Discount top-right, 8pt from edges -->
<constraint
firstAttribute=
"trailing"
secondItem=
"DSC-vw-001"
secondAttribute=
"trailing"
constant=
"8"
id=
"DSC-tr2-001"
/>
<constraint
firstItem=
"DSC-vw-001"
firstAttribute=
"top"
secondItem=
"TOP-vw-001"
secondAttribute=
"top"
constant=
"8"
id=
"DSC-top-001"
/>
<!-- Top view height -->
<constraint
firstAttribute=
"height"
constant=
"140"
id=
"TOP-h-001"
/>
</constraints>
</view>
<!-- Bottom View: white, text labels -->
<view
contentMode=
"scaleToFill"
translatesAutoresizingMaskIntoConstraints=
"NO"
id=
"BTM-vw-001"
userLabel=
"BottomView"
>
<rect
key=
"frame"
x=
"0.0"
y=
"140"
width=
"170"
height=
"140"
/>
<subviews>
<!-- Merchant name label -->
<label
opaque=
"NO"
userInteractionEnabled=
"NO"
contentMode=
"left"
horizontalHuggingPriority=
"251"
verticalHuggingPriority=
"251"
text=
"Merchant"
textAlignment=
"natural"
lineBreakMode=
"tailTruncation"
baselineAdjustment=
"alignBaselines"
adjustsFontSizeToFit=
"NO"
translatesAutoresizingMaskIntoConstraints=
"NO"
id=
"MRC-lbl-001"
>
<rect
key=
"frame"
x=
"10"
y=
"10"
width=
"150"
height=
"16"
/>
<fontDescription
key=
"fontDescription"
type=
"system"
pointSize=
"12"
/>
<nil
key=
"textColor"
/>
<nil
key=
"highlightedColor"
/>
</label>
<!-- Title label (bold) -->
<label
opaque=
"NO"
userInteractionEnabled=
"NO"
contentMode=
"left"
horizontalHuggingPriority=
"251"
verticalHuggingPriority=
"251"
text=
"Title"
textAlignment=
"natural"
lineBreakMode=
"tailTruncation"
numberOfLines=
"2"
baselineAdjustment=
"alignBaselines"
adjustsFontSizeToFit=
"NO"
translatesAutoresizingMaskIntoConstraints=
"NO"
id=
"TTL-lbl-001"
>
<rect
key=
"frame"
x=
"10"
y=
"30"
width=
"150"
height=
"40"
/>
<fontDescription
key=
"fontDescription"
type=
"system"
pointSize=
"15"
/>
<nil
key=
"textColor"
/>
<nil
key=
"highlightedColor"
/>
</label>
<!-- Subtitle label -->
<label
opaque=
"NO"
userInteractionEnabled=
"NO"
contentMode=
"left"
horizontalHuggingPriority=
"251"
verticalHuggingPriority=
"251"
text=
"Subtitle"
textAlignment=
"natural"
lineBreakMode=
"tailTruncation"
numberOfLines=
"2"
baselineAdjustment=
"alignBaselines"
adjustsFontSizeToFit=
"NO"
translatesAutoresizingMaskIntoConstraints=
"NO"
id=
"SUB-lbl-001"
>
<rect
key=
"frame"
x=
"10"
y=
"74"
width=
"150"
height=
"34"
/>
<fontDescription
key=
"fontDescription"
type=
"system"
pointSize=
"13"
/>
<nil
key=
"textColor"
/>
<nil
key=
"highlightedColor"
/>
</label>
<!-- Expiration label -->
<label
opaque=
"NO"
userInteractionEnabled=
"NO"
contentMode=
"left"
horizontalHuggingPriority=
"251"
verticalHuggingPriority=
"251"
text=
"until 30-09"
textAlignment=
"natural"
lineBreakMode=
"tailTruncation"
baselineAdjustment=
"alignBaselines"
adjustsFontSizeToFit=
"NO"
translatesAutoresizingMaskIntoConstraints=
"NO"
id=
"EXP-lbl-001"
>
<rect
key=
"frame"
x=
"10"
y=
"112"
width=
"150"
height=
"16"
/>
<fontDescription
key=
"fontDescription"
type=
"system"
pointSize=
"12"
/>
<nil
key=
"textColor"
/>
<nil
key=
"highlightedColor"
/>
</label>
</subviews>
<color
key=
"backgroundColor"
white=
"1"
alpha=
"1"
colorSpace=
"custom"
customColorSpace=
"genericGamma22GrayColorSpace"
/>
<constraints>
<!-- Merchant label -->
<constraint
firstItem=
"MRC-lbl-001"
firstAttribute=
"top"
secondItem=
"BTM-vw-001"
secondAttribute=
"top"
constant=
"10"
id=
"MRC-t-001"
/>
<constraint
firstItem=
"MRC-lbl-001"
firstAttribute=
"leading"
secondItem=
"BTM-vw-001"
secondAttribute=
"leading"
constant=
"10"
id=
"MRC-l-001"
/>
<constraint
firstAttribute=
"trailing"
secondItem=
"MRC-lbl-001"
secondAttribute=
"trailing"
constant=
"10"
id=
"MRC-tr-001"
/>
<!-- Title below merchant, 4pt gap -->
<constraint
firstItem=
"TTL-lbl-001"
firstAttribute=
"top"
secondItem=
"MRC-lbl-001"
secondAttribute=
"bottom"
constant=
"4"
id=
"TTL-t-001"
/>
<constraint
firstItem=
"TTL-lbl-001"
firstAttribute=
"leading"
secondItem=
"BTM-vw-001"
secondAttribute=
"leading"
constant=
"10"
id=
"TTL-l-001"
/>
<constraint
firstAttribute=
"trailing"
secondItem=
"TTL-lbl-001"
secondAttribute=
"trailing"
constant=
"10"
id=
"TTL-tr-001"
/>
<!-- Subtitle below title, 4pt gap -->
<constraint
firstItem=
"SUB-lbl-001"
firstAttribute=
"top"
secondItem=
"TTL-lbl-001"
secondAttribute=
"bottom"
constant=
"4"
id=
"SUB-t-001"
/>
<constraint
firstItem=
"SUB-lbl-001"
firstAttribute=
"leading"
secondItem=
"BTM-vw-001"
secondAttribute=
"leading"
constant=
"10"
id=
"SUB-l-001"
/>
<constraint
firstAttribute=
"trailing"
secondItem=
"SUB-lbl-001"
secondAttribute=
"trailing"
constant=
"10"
id=
"SUB-tr-001"
/>
<!-- Expiration pinned to bottom -->
<constraint
firstAttribute=
"bottom"
secondItem=
"EXP-lbl-001"
secondAttribute=
"bottom"
constant=
"10"
id=
"EXP-b-001"
/>
<constraint
firstItem=
"EXP-lbl-001"
firstAttribute=
"leading"
secondItem=
"BTM-vw-001"
secondAttribute=
"leading"
constant=
"10"
id=
"EXP-l-001"
/>
<constraint
firstAttribute=
"trailing"
secondItem=
"EXP-lbl-001"
secondAttribute=
"trailing"
constant=
"10"
id=
"EXP-tr-001"
/>
</constraints>
</view>
</subviews>
<color
key=
"backgroundColor"
white=
"1"
alpha=
"1"
colorSpace=
"custom"
customColorSpace=
"genericGamma22GrayColorSpace"
/>
<constraints>
<!-- Top view pinned to top -->
<constraint
firstItem=
"TOP-vw-001"
firstAttribute=
"top"
secondItem=
"A1B-CD-EFG"
secondAttribute=
"top"
id=
"TOP-t-p-001"
/>
<constraint
firstItem=
"TOP-vw-001"
firstAttribute=
"leading"
secondItem=
"A1B-CD-EFG"
secondAttribute=
"leading"
id=
"TOP-l-p-001"
/>
<constraint
firstAttribute=
"trailing"
secondItem=
"TOP-vw-001"
secondAttribute=
"trailing"
id=
"TOP-tr-p-001"
/>
<!-- Bottom view below top view -->
<constraint
firstItem=
"BTM-vw-001"
firstAttribute=
"top"
secondItem=
"TOP-vw-001"
secondAttribute=
"bottom"
id=
"BTM-t-p-001"
/>
<constraint
firstItem=
"BTM-vw-001"
firstAttribute=
"leading"
secondItem=
"A1B-CD-EFG"
secondAttribute=
"leading"
id=
"BTM-l-p-001"
/>
<constraint
firstAttribute=
"trailing"
secondItem=
"BTM-vw-001"
secondAttribute=
"trailing"
id=
"BTM-tr-p-001"
/>
<constraint
firstAttribute=
"bottom"
secondItem=
"BTM-vw-001"
secondAttribute=
"bottom"
id=
"BTM-b-p-001"
/>
</constraints>
</view>
</subviews>
<constraints>
<constraint
firstItem=
"A1B-CD-EFG"
firstAttribute=
"top"
secondItem=
"gTV-IL-0wX"
secondAttribute=
"top"
id=
"PV-t-001"
/>
<constraint
firstItem=
"A1B-CD-EFG"
firstAttribute=
"leading"
secondItem=
"gTV-IL-0wX"
secondAttribute=
"leading"
id=
"PV-l-001"
/>
<constraint
firstAttribute=
"trailing"
secondItem=
"A1B-CD-EFG"
secondAttribute=
"trailing"
id=
"PV-tr-001"
/>
<constraint
firstAttribute=
"bottom"
secondItem=
"A1B-CD-EFG"
secondAttribute=
"bottom"
id=
"PV-b-001"
/>
</constraints>
</view>
<viewLayoutGuide
key=
"safeArea"
id=
"ZTg-uK-7eu"
/>
<connections>
<outlet
property=
"bannerImage"
destination=
"BNR-img-001"
id=
"BNR-out-001"
/>
<outlet
property=
"discountLabel"
destination=
"DSC-lbl-001"
id=
"DSC-out-001"
/>
<outlet
property=
"discountView"
destination=
"DSC-vw-001"
id=
"DSC-out-002"
/>
<outlet
property=
"expirationLabel"
destination=
"EXP-lbl-001"
id=
"EXP-out-001"
/>
<outlet
property=
"logoImage"
destination=
"LGO-img-001"
id=
"LGO-out-001"
/>
<outlet
property=
"merchantNameLabel"
destination=
"MRC-lbl-001"
id=
"MRC-out-001"
/>
<outlet
property=
"parentView"
destination=
"A1B-CD-EFG"
id=
"PV-out-001"
/>
<outlet
property=
"subtitleLabel"
destination=
"SUB-lbl-001"
id=
"SUB-out-001"
/>
<outlet
property=
"titleLabel"
destination=
"TTL-lbl-001"
id=
"TTL-out-001"
/>
</connections>
<size
key=
"customSize"
width=
"170"
height=
"280"
/>
<point
key=
"canvasLocation"
x=
"50"
y=
"50"
/>
</collectionViewCell>
</objects>
<resources>
<systemColor
name=
"systemBackgroundColor"
>
<color
white=
"1"
alpha=
"1"
colorSpace=
"custom"
customColorSpace=
"genericGamma22GrayColorSpace"
/>
</systemColor>
</resources>
</document>
...
...
SwiftWarplyFramework/SwiftWarplyFramework/cells/CategoryOffersGridTableViewCell/CategoryOffersGridTableViewCell.swift
View file @
03fbadc
...
...
@@ -12,52 +12,64 @@ public class CategoryOffersGridTableViewCell: UITableViewCell {
@IBOutlet
weak
var
collectionView
:
UICollectionView
!
@IBOutlet
weak
var
collectionViewHeightConstraint
:
NSLayoutConstraint
!
var
data
:
SectionModel
?
weak
var
parentViewController
:
UIViewController
?
public
override
func
awakeFromNib
()
{
super
.
awakeFromNib
()
// Initialization code
setupCollectionView
()
}
public
override
func
setSelected
(
_
selected
:
Bool
,
animated
:
Bool
)
{
super
.
setSelected
(
selected
,
animated
:
animated
)
// Configure the view for the selected state
}
private
func
setupCollectionView
()
{
collectionView
.
delegate
=
self
collectionView
.
dataSource
=
self
collectionView
.
backgroundColor
=
.
clear
collectionView
.
isScrollEnabled
=
false
// Scroll is handled by the outer TableView
collectionView
.
isScrollEnabled
=
false
XIBLoader
.
registerCollectionViewCell
(
collectionView
,
cellClass
:
UICollectionViewCell
.
self
,
nibName
:
"CategoryOfferCollectionViewCell"
,
identifier
:
"CategoryOfferCollectionViewCell"
)
if
let
layout
=
collectionView
.
collectionViewLayout
as?
UICollectionViewFlowLayout
{
layout
.
minimumInteritemSpacing
=
1
6
layout
.
minimumInteritemSpacing
=
1
2
layout
.
minimumLineSpacing
=
16
layout
.
sectionInset
=
UIEdgeInsets
(
top
:
16
,
left
:
16
,
bottom
:
16
,
right
:
16
)
}
}
public
override
func
setSelected
(
_
selected
:
Bool
,
animated
:
Bool
)
{
super
.
setSelected
(
selected
,
animated
:
animated
)
}
func
configureCell
(
with
sectionData
:
SectionModel
?,
parentViewController
:
UIViewController
?)
{
self
.
data
=
sectionData
self
.
parentViewController
=
parentViewController
collectionView
.
reloadData
()
// Use layoutIfNeeded to calculate content size and set the height constraint
collectionView
.
layoutIfNeeded
()
let
height
=
collectionView
.
collectionViewLayout
.
collectionViewContentSize
.
height
collectionViewHeightConstraint
.
constant
=
height
// Calculate and set the collection view height so the table view cell expands correctly
DispatchQueue
.
main
.
async
{
self
.
collectionView
.
layoutIfNeeded
()
let
height
=
self
.
collectionView
.
collectionViewLayout
.
collectionViewContentSize
.
height
self
.
collectionViewHeightConstraint
.
constant
=
max
(
height
,
1
)
// Notify the parent table view to recalculate its layout
if
let
tableView
=
self
.
parentViewController
?
.
view
.
subviews
.
first
(
where
:
{
$0
is
UITableView
})
as?
UITableView
{
tableView
.
beginUpdates
()
tableView
.
endUpdates
()
}
}
}
// Compute item size for 2-column grid
private
func
itemSize
()
->
CGSize
{
let
totalWidth
=
collectionView
.
bounds
.
width
>
0
?
collectionView
.
bounds
.
width
:
UIScreen
.
main
.
bounds
.
width
let
inset
:
CGFloat
=
16
let
spacing
:
CGFloat
=
12
let
availableWidth
=
totalWidth
-
(
inset
*
2
)
-
spacing
let
itemWidth
=
floor
(
availableWidth
/
2
)
let
itemHeight
=
itemWidth
*
1.65
// ratio matching the design card proportions
return
CGSize
(
width
:
itemWidth
,
height
:
itemHeight
)
}
}
...
...
@@ -73,13 +85,13 @@ extension CategoryOffersGridTableViewCell: UICollectionViewDataSource, UICollect
public
func
collectionView
(
_
collectionView
:
UICollectionView
,
cellForItemAt
indexPath
:
IndexPath
)
->
UICollectionViewCell
{
let
cell
=
collectionView
.
dequeueReusableCell
(
withReuseIdentifier
:
"CategoryOfferCollectionViewCell"
,
for
:
indexPath
)
as!
CategoryOfferCollectionViewCell
guard
let
data
=
self
.
data
,
let
items
=
data
.
items
,
indexPath
.
row
<
items
.
count
else
{
return
cell
}
switch
data
.
itemType
{
case
.
couponSets
:
if
let
couponSet
=
items
[
indexPath
.
row
]
as?
CouponSetItemModel
{
...
...
@@ -90,49 +102,46 @@ extension CategoryOffersGridTableViewCell: UICollectionViewDataSource, UICollect
cell
.
configureCell
(
data
:
offer
)
}
}
return
cell
}
public
func
collectionView
(
_
collectionView
:
UICollectionView
,
didSelectItemAt
indexPath
:
IndexPath
)
{
guard
let
data
=
self
.
data
,
let
items
=
data
.
items
,
indexPath
.
row
<
items
.
count
else
{
return
}
// Handle navigation based on item type
switch
data
.
itemType
{
case
.
couponSets
:
if
let
couponSet
=
items
[
indexPath
.
row
]
as?
CouponSetItemModel
{
let
storyboard
=
UIStoryboard
(
name
:
"Main"
,
bundle
:
Bundle
.
frameworkResourceBundle
)
if
let
vc
=
storyboard
.
instantiateViewController
(
withIdentifier
:
"CouponsetViewController"
)
as?
CouponsetViewController
{
vc
.
couponset
=
couponSet
self
.
parentViewController
?
.
navigationController
?
.
pushViewController
(
vc
,
animated
:
true
)
}
let
vc
=
CouponsetViewController
(
nibName
:
"CouponsetViewController"
,
bundle
:
Bundle
.
frameworkResourceBundle
)
vc
.
couponset
=
couponSet
parentViewController
?
.
navigationController
?
.
pushViewController
(
vc
,
animated
:
true
)
}
default
:
if
let
offer
=
items
[
indexPath
.
row
]
as?
OfferModel
{
// Determine if it's a campaign or other offer and navigate appropriately
// (Using existing patterns from MyRewardsViewController)
let
storyboard
=
UIStoryboard
(
name
:
"Main"
,
bundle
:
Bundle
.
frameworkResourceBundle
)
if
let
vc
=
storyboard
.
instantiateViewController
(
withIdentifier
:
"CampaignViewController"
)
as?
CampaignViewController
{
vc
.
campaignUrl
=
offer
.
campaignUrl
// Assuming OfferModel has this
self
.
parentViewController
?
.
navigationController
?
.
pushViewController
(
vc
,
animated
:
true
)
}
let
vc
=
CouponViewController
(
nibName
:
"CouponViewController"
,
bundle
:
Bundle
.
frameworkResourceBundle
)
vc
.
offer
=
offer
parentViewController
?
.
navigationController
?
.
pushViewController
(
vc
,
animated
:
true
)
}
}
}
public
func
collectionView
(
_
collectionView
:
UICollectionView
,
layout
collectionViewLayout
:
UICollectionViewLayout
,
sizeForItemAt
indexPath
:
IndexPath
)
->
CGSize
{
// Calculate width for 2 columns with spacing
let
padding
:
CGFloat
=
16
*
3
// left + middle + right padding
let
availableWidth
=
collectionView
.
frame
.
width
-
padding
let
itemWidth
=
availableWidth
/
2
// Adjust height as needed based on design (aspect ratio or fixed)
let
itemHeight
=
itemWidth
*
1.3
// Approximation from screenshot
return
CGSize
(
width
:
itemWidth
,
height
:
itemHeight
)
return
itemSize
()
}
public
func
collectionView
(
_
collectionView
:
UICollectionView
,
layout
collectionViewLayout
:
UICollectionViewLayout
,
minimumLineSpacingForSectionAt
section
:
Int
)
->
CGFloat
{
return
16
}
public
func
collectionView
(
_
collectionView
:
UICollectionView
,
layout
collectionViewLayout
:
UICollectionViewLayout
,
minimumInteritemSpacingForSectionAt
section
:
Int
)
->
CGFloat
{
return
12
}
public
func
collectionView
(
_
collectionView
:
UICollectionView
,
layout
collectionViewLayout
:
UICollectionViewLayout
,
insetForSectionAt
section
:
Int
)
->
UIEdgeInsets
{
return
UIEdgeInsets
(
top
:
16
,
left
:
16
,
bottom
:
16
,
right
:
16
)
}
}
...
...
SwiftWarplyFramework/SwiftWarplyFramework/cells/MyRewardsOffersScrollTableViewCell/MyRewardsOffersScrollTableViewCell.swift
View file @
03fbadc
...
...
@@ -10,6 +10,7 @@ import UIKit
protocol
MyRewardsOffersScrollTableViewCellDelegate
:
AnyObject
{
func
didSelectOffer
(
_
offer
:
OfferModel
)
func
didSelectCouponSet
(
_
couponSet
:
CouponSetItemModel
)
func
didSelectAllOffers
(
_
section
:
SectionModel
)
}
@objc(MyRewardsOffersScrollTableViewCell)
...
...
@@ -29,19 +30,19 @@ public class MyRewardsOffersScrollTableViewCell: UITableViewCell {
super
.
awakeFromNib
()
// Initialization code
// allButtonView.layer.borderWidth = 1.0
// allButtonView.layer.borderColor = UIColor(rgb: 0x000F1E).cgColor
// allButtonView.layer.cornerRadius = 4.0
allButtonArrowImage
.
image
=
UIImage
(
named
:
"arrow_right_blue"
,
in
:
Bundle
.
frameworkResourceBundle
,
compatibleWith
:
nil
)
// allButtonLabel.text = "Όλα"
allButtonLabel
.
text
=
"All"
allButtonLabel
.
font
=
UIFont
(
name
:
"PingLCG-Regular"
,
size
:
15
)
allButtonLabel
.
textColor
=
UIColor
(
rgb
:
0x004E6E
)
allButtonLabel
.
frame
.
size
.
width
=
allButtonLabel
.
intrinsicContentSize
.
width
allButtonLabel
.
frame
.
size
.
height
=
allButtonLabel
.
intrinsicContentSize
.
height
// Add tap gesture to allButtonView
let
tapGesture
=
UITapGestureRecognizer
(
target
:
self
,
action
:
#selector(
allButtonTapped
)
)
allButtonView
.
isUserInteractionEnabled
=
true
allButtonView
.
addGestureRecognizer
(
tapGesture
)
// UPDATED: Safe XIB registration for collection view cells
registerCollectionViewCells
()
...
...
@@ -56,6 +57,11 @@ public class MyRewardsOffersScrollTableViewCell: UITableViewCell {
collectionView
.
dataSource
=
self
}
@objc
private
func
allButtonTapped
()
{
guard
let
data
=
data
else
{
return
}
delegate
?
.
didSelectAllOffers
(
data
)
}
// NEW: Safe collection view cell registration
private
func
registerCollectionViewCells
()
{
XIBLoader
.
registerCollectionViewCell
(
...
...
@@ -109,20 +115,11 @@ public class MyRewardsOffersScrollTableViewCell: UITableViewCell {
collectionViewBottom
.
constant
=
0
}
// Update collection view height based on section
// if data?.title == "Αγαπημένα" {
// collectionViewHeightConstraint.constant = 350 // Match cell height
// } else {
collectionViewHeightConstraint
.
constant
=
232
// Default height
// }
collectionViewHeightConstraint
.
constant
=
232
// Default height
// Configure layout based on section type
if
let
layout
=
collectionView
.
collectionViewLayout
as?
UICollectionViewFlowLayout
{
// if data?.title == "Αγαπημένα" {
// layout.minimumLineSpacing = 24
// } else {
layout
.
minimumLineSpacing
=
7
// }
layout
.
minimumLineSpacing
=
7
}
let
catBoldText
=
(
data
?
.
title
??
""
)
+
" "
...
...
@@ -138,13 +135,11 @@ public class MyRewardsOffersScrollTableViewCell: UITableViewCell {
categoryLabel
.
attributedText
=
catAttributedString
self
.
collectionView
.
reloadData
();
}
}
extension
MyRewardsOffersScrollTableViewCell
:
UICollectionViewDataSource
,
UICollectionViewDelegate
,
UICollectionViewDelegateFlowLayout
{
public
func
numberOfSections
(
in
collectionView
:
UICollectionView
)
->
Int
{
return
1
}
...
...
@@ -189,11 +184,9 @@ extension MyRewardsOffersScrollTableViewCell: UICollectionViewDataSource, UIColl
switch
data
.
itemType
{
case
.
couponSets
:
if
let
couponSet
=
items
[
indexPath
.
row
]
as?
CouponSetItemModel
{
// Pass CouponSetItemModel directly to new delegate method
delegate
?
.
didSelectCouponSet
(
couponSet
)
}
default
:
// Handle OfferModel directly for ProfileViewController compatibility
if
let
offer
=
items
[
indexPath
.
row
]
as?
OfferModel
{
delegate
?
.
didSelectOffer
(
offer
)
}
...
...
@@ -202,20 +195,12 @@ extension MyRewardsOffersScrollTableViewCell: UICollectionViewDataSource, UIColl
// MARK: - UICollectionViewDelegateFlowLayout
public
func
collectionView
(
_
collectionView
:
UICollectionView
,
layout
collectionViewLayout
:
UICollectionViewLayout
,
sizeForItemAt
indexPath
:
IndexPath
)
->
CGSize
{
// if self.data?.title == "Αγαπημένα" {
// return CGSize(width: 275, height: 350)
// } else {
return
CGSize
(
width
:
257
,
height
:
232
)
// }
return
CGSize
(
width
:
257
,
height
:
232
)
}
// Distance Between Item Cells
public
func
collectionView
(
_
collectionView
:
UICollectionView
,
layout
collectionViewLayout
:
UICollectionViewLayout
,
minimumLineSpacingForSectionAt
section
:
Int
)
->
CGFloat
{
// if self.data?.title == "Αγαπημένα" {
// return 24
// } else {
return
7
// }
return
7
}
public
func
collectionView
(
_
collectionView
:
UICollectionView
,
layout
collectionViewLayout
:
UICollectionViewLayout
,
minimumInteritemSpacingForSectionAt
section
:
Int
)
->
CGFloat
{
...
...
SwiftWarplyFramework/SwiftWarplyFramework/screens/CategoryOffersViewController/CategoryOffersViewController.swift
View file @
03fbadc
...
...
@@ -8,60 +8,71 @@
import
UIKit
@objc
public
class
CategoryOffersViewController
:
UIViewController
{
@IBOutlet
weak
var
tableView
:
UITableView
!
public
var
sectionData
:
SectionModel
?
public
override
func
viewDidLoad
()
{
super
.
viewDidLoad
()
self
.
navigationController
?
.
setNavigationBarHidden
(
false
,
animated
:
false
)
setBackButton
()
setupTableView
()
}
private
func
setupTableView
()
{
tableView
.
delegate
=
self
tableView
.
dataSource
=
self
tableView
.
separatorStyle
=
.
none
tableView
.
backgroundColor
=
.
white
tableView
.
register
(
UINib
(
nibName
:
"CategoryOffersHeaderTableViewCell"
,
bundle
:
Bundle
.
frameworkResourceBundle
),
forCellReuseIdentifier
:
"CategoryOffersHeaderTableViewCell"
)
tableView
.
register
(
UINib
(
nibName
:
"CategoryOffersGridTableViewCell"
,
bundle
:
Bundle
.
frameworkResourceBundle
),
forCellReuseIdentifier
:
"CategoryOffersGridTableViewCell"
)
tableView
.
estimatedRowHeight
=
100
tableView
.
rowHeight
=
UITableView
.
automaticDimension
tableView
.
register
(
UINib
(
nibName
:
"CategoryOffersHeaderTableViewCell"
,
bundle
:
Bundle
.
frameworkResourceBundle
),
forCellReuseIdentifier
:
"CategoryOffersHeaderTableViewCell"
)
tableView
.
register
(
UINib
(
nibName
:
"CategoryOffersGridTableViewCell"
,
bundle
:
Bundle
.
frameworkResourceBundle
),
forCellReuseIdentifier
:
"CategoryOffersGridTableViewCell"
)
}
}
extension
CategoryOffersViewController
:
UITableViewDelegate
,
UITableViewDataSource
{
public
func
numberOfSections
(
in
tableView
:
UITableView
)
->
Int
{
return
1
}
public
func
tableView
(
_
tableView
:
UITableView
,
numberOfRowsInSection
section
:
Int
)
->
Int
{
return
2
//
Header +
Grid
return
2
//
Row 0: Header, Row 1:
Grid
}
public
func
tableView
(
_
tableView
:
UITableView
,
cellForRowAt
indexPath
:
IndexPath
)
->
UITableViewCell
{
if
indexPath
.
row
==
0
{
let
cell
=
tableView
.
dequeueReusableCell
(
withIdentifier
:
"CategoryOffersHeaderTableViewCell"
,
for
:
indexPath
)
as!
CategoryOffersHeaderTableViewCell
if
let
title
=
sectionData
?
.
title
{
cell
.
headerLabel
.
text
=
title
}
cell
.
headerLabel
.
text
=
sectionData
?
.
title
??
""
cell
.
selectionStyle
=
.
none
return
cell
}
else
{
let
cell
=
tableView
.
dequeueReusableCell
(
withIdentifier
:
"CategoryOffersGridTableViewCell"
,
for
:
indexPath
)
as!
CategoryOffersGridTableViewCell
cell
.
configureCell
(
with
:
sectionData
,
parentViewController
:
self
)
cell
.
selectionStyle
=
.
none
return
cell
}
}
public
func
tableView
(
_
tableView
:
UITableView
,
heightForRowAt
indexPath
:
IndexPath
)
->
CGFloat
{
return
UITableView
.
automaticDimension
}
public
func
tableView
(
_
tableView
:
UITableView
,
estimatedHeightForRowAt
indexPath
:
IndexPath
)
->
CGFloat
{
if
indexPath
.
row
==
0
{
return
UITableView
.
automaticDimension
}
else
{
return
UITableView
.
automaticDimension
// Or a calculated height depending on content
return
100
}
return
600
}
}
...
...
SwiftWarplyFramework/SwiftWarplyFramework/screens/MyRewardsViewController/MyRewardsViewController.swift
View file @
03fbadc
...
...
@@ -802,4 +802,15 @@ extension MyRewardsViewController: MyRewardsOffersScrollTableViewCellDelegate {
func
didSelectCouponSet
(
_
couponSet
:
CouponSetItemModel
)
{
openCouponsetViewController
(
with
:
couponSet
)
}
func
didSelectAllOffers
(
_
section
:
SectionModel
)
{
let
vc
=
CategoryOffersViewController
(
nibName
:
"CategoryOffersViewController"
,
bundle
:
Bundle
.
frameworkResourceBundle
)
vc
.
sectionData
=
section
if
let
navigationController
=
self
.
navigationController
{
navigationController
.
pushViewController
(
vc
,
animated
:
true
)
}
else
{
vc
.
modalPresentationStyle
=
.
fullScreen
self
.
present
(
vc
,
animated
:
true
,
completion
:
nil
)
}
}
}
...
...
SwiftWarplyFramework/SwiftWarplyFramework/screens/ProfileViewController/ProfileViewController.swift
View file @
03fbadc
...
...
@@ -545,6 +545,11 @@ extension ProfileViewController: MyRewardsOffersScrollTableViewCellDelegate {
// ProfileViewController doesn't handle coupon sets, so just log
print
(
"CouponSet selected in ProfileViewController:
\(
couponSet
.
_name
)
"
)
}
func
didSelectAllOffers
(
_
section
:
SectionModel
)
{
// ProfileViewController doesn't navigate to category offers
print
(
"⚠️ [ProfileVC] didSelectAllOffers — not handled"
)
}
}
// Add delegate conformance
...
...
Please
register
or
login
to post a comment