Skip to content

Commit 608bfdb

Browse files
authored
Merge pull request onevcat#2302 from onevcat/feature/live-photo
Add support for Live Photo loading from network
2 parents e72fedd + 27f4a73 commit 608bfdb

23 files changed

+1941
-61
lines changed

Demo/Demo/Kingfisher-Demo/Base.lproj/Main.storyboard

+43-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="peg-r0-mlo">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23094" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="peg-r0-mlo">
33
<device id="retina5_5" orientation="portrait" appearance="dark"/>
44
<dependencies>
55
<deployment identifier="iOS"/>
6-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22684"/>
6+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23084"/>
77
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
88
<capability name="System colors in document resources" minToolsVersion="11.0"/>
99
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@@ -491,9 +491,33 @@
491491
<segue destination="wco-eY-gNu" kind="show" id="KCP-ab-diO"/>
492492
</connections>
493493
</tableViewCell>
494-
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="TIF-8x-GLM">
494+
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="8uq-CX-Fxl">
495495
<rect key="frame" x="0.0" y="710" width="414" height="44"/>
496496
<autoresizingMask key="autoresizingMask"/>
497+
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="8uq-CX-Fxl" id="I9G-72-N8J">
498+
<rect key="frame" x="0.0" y="0.0" width="414" height="44"/>
499+
<autoresizingMask key="autoresizingMask"/>
500+
<subviews>
501+
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Live Photo" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mXz-QJ-f80">
502+
<rect key="frame" x="20" y="11.666666666666664" width="80" height="21"/>
503+
<fontDescription key="fontDescription" type="system" pointSize="17"/>
504+
<nil key="textColor"/>
505+
<nil key="highlightedColor"/>
506+
</label>
507+
</subviews>
508+
<constraints>
509+
<constraint firstItem="mXz-QJ-f80" firstAttribute="leading" secondItem="I9G-72-N8J" secondAttribute="leading" constant="20" symbolic="YES" id="1BM-Eu-bcs"/>
510+
<constraint firstItem="mXz-QJ-f80" firstAttribute="centerY" secondItem="I9G-72-N8J" secondAttribute="centerY" id="Fqb-ZQ-J3L"/>
511+
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="mXz-QJ-f80" secondAttribute="trailing" constant="20" symbolic="YES" id="fAH-HG-EXN"/>
512+
</constraints>
513+
</tableViewCellContentView>
514+
<connections>
515+
<segue destination="nhf-ZY-JwU" kind="show" id="Srz-py-yg9"/>
516+
</connections>
517+
</tableViewCell>
518+
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="TIF-8x-GLM">
519+
<rect key="frame" x="0.0" y="754" width="414" height="44"/>
520+
<autoresizingMask key="autoresizingMask"/>
497521
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="TIF-8x-GLM" id="ykx-Ds-PkP">
498522
<rect key="frame" x="0.0" y="0.0" width="414" height="44"/>
499523
<autoresizingMask key="autoresizingMask"/>
@@ -992,6 +1016,22 @@
9921016
</objects>
9931017
<point key="canvasLocation" x="2654" y="1061"/>
9941018
</scene>
1019+
<!--Live Photo View Controller-->
1020+
<scene sceneID="50O-N8-WQ3">
1021+
<objects>
1022+
<viewController id="nhf-ZY-JwU" customClass="LivePhotoViewController" customModule="Kingfisher_Demo" customModuleProvider="target" sceneMemberID="viewController">
1023+
<view key="view" contentMode="scaleToFill" id="G81-wm-Fnw">
1024+
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
1025+
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
1026+
<viewLayoutGuide key="safeArea" id="12L-DC-epo"/>
1027+
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
1028+
</view>
1029+
<navigationItem key="navigationItem" id="bYb-CA-CnJ"/>
1030+
</viewController>
1031+
<placeholder placeholderIdentifier="IBFirstResponder" id="y5S-MW-IuF" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
1032+
</objects>
1033+
<point key="canvasLocation" x="1851" y="2398"/>
1034+
</scene>
9951035
<!--Asset Image Generator View Controller-->
9961036
<scene sceneID="PCw-9j-oCu">
9971037
<objects>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//
2+
// LivePhotoViewController.swift
3+
// Kingfisher
4+
//
5+
// Created by onevcat on 2024/10/05.
6+
//
7+
// Copyright (c) 2024 Wei Wang <[email protected]>
8+
//
9+
// Permission is hereby granted, free of charge, to any person obtaining a copy
10+
// of this software and associated documentation files (the "Software"), to deal
11+
// in the Software without restriction, including without limitation the rights
12+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
// copies of the Software, and to permit persons to whom the Software is
14+
// furnished to do so, subject to the following conditions:
15+
//
16+
// The above copyright notice and this permission notice shall be included in
17+
// all copies or substantial portions of the Software.
18+
//
19+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
// THE SOFTWARE.
26+
27+
import UIKit
28+
import PhotosUI
29+
import Kingfisher
30+
31+
class LivePhotoViewController: UIViewController {
32+
33+
private var livePhotoView: PHLivePhotoView!
34+
35+
override func viewDidLoad() {
36+
super.viewDidLoad()
37+
title = "Live Photo"
38+
setupOperationNavigationBar()
39+
40+
livePhotoView = PHLivePhotoView()
41+
livePhotoView.translatesAutoresizingMaskIntoConstraints = false
42+
43+
view.addSubview(livePhotoView)
44+
NSLayoutConstraint.activate([
45+
livePhotoView.heightAnchor.constraint(equalToConstant: 300),
46+
livePhotoView.widthAnchor.constraint(equalToConstant: 300),
47+
livePhotoView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
48+
livePhotoView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -30)
49+
])
50+
51+
let urls = [
52+
"https://github.com/onevcat/Kingfisher-TestImages/raw/refs/heads/master/LivePhotos/live_photo_sample.HEIC",
53+
"https://github.com/onevcat/Kingfisher-TestImages/raw/refs/heads/master/LivePhotos/live_photo_sample.MOV"
54+
].compactMap(URL.init)
55+
livePhotoView.kf.setImage(with: urls, completionHandler: { result in
56+
switch result {
57+
case .success(let r):
58+
print("Live Photo done. \(r.loadingInfo.cacheType)")
59+
print("Info: \(String(describing: r.info))")
60+
case .failure(let error):
61+
print("Live Photo error: \(error)")
62+
}
63+
})
64+
}
65+
}

Demo/Kingfisher-Demo.xcodeproj/project.pbxproj

+4
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
D12E0CB61C47F9C100AC98AD /* NormalLoadingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D12E0C941C47F91800AC98AD /* NormalLoadingViewController.swift */; };
5555
D12EB83E24DD902300329EE1 /* TextAttachmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D12EB83D24DD902300329EE1 /* TextAttachmentViewController.swift */; };
5656
D12EB84024DDB9E100329EE1 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D12EB83F24DDB9E000329EE1 /* LaunchScreen.storyboard */; };
57+
D12F67682CB10AE000AB63AB /* LivePhotoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D12F67672CB10AD900AB63AB /* LivePhotoViewController.swift */; };
5758
D1679A461C4E78B20020FD12 /* Kingfisher-watchOS-Demo Extension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D1679A451C4E78B20020FD12 /* Kingfisher-watchOS-Demo Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
5859
D16CC3D824E03FEA00F1A515 /* AVAssetImageGeneratorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D16CC3D724E03FEA00F1A515 /* AVAssetImageGeneratorViewController.swift */; };
5960
D198F41E25EDC11500C53E0D /* LazyVStackDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D198F41D25EDC11500C53E0D /* LazyVStackDemo.swift */; };
@@ -204,6 +205,7 @@
204205
D12E0CA11C47F92200AC98AD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
205206
D12EB83D24DD902300329EE1 /* TextAttachmentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextAttachmentViewController.swift; sourceTree = "<group>"; };
206207
D12EB83F24DDB9E000329EE1 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
208+
D12F67672CB10AD900AB63AB /* LivePhotoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LivePhotoViewController.swift; sourceTree = "<group>"; };
207209
D13F49C21BEDA53F00CE335D /* Kingfisher-tvOS-Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Kingfisher-tvOS-Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; };
208210
D16218A4238EAA67004A1C6C /* Kingfisher-Demo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Kingfisher-Demo.entitlements"; sourceTree = "<group>"; };
209211
D1679A391C4E78B20020FD12 /* Kingfisher-watchOS-Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Kingfisher-watchOS-Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -386,6 +388,7 @@
386388
D1A1CCA921A1936300263AD8 /* ViewControllers */ = {
387389
isa = PBXGroup;
388390
children = (
391+
D12F67672CB10AD900AB63AB /* LivePhotoViewController.swift */,
389392
D10AC99721A300C9005F057C /* ProcessorCollectionViewController.swift */,
390393
4B1C7A3C21A256E300CE9D31 /* InfinityCollectionViewController.swift */,
391394
D1CE1BCF21A1AFA300419000 /* TransitionViewController.swift */,
@@ -731,6 +734,7 @@
731734
078DCB512BCFEFB40008114E /* PHPickerResultViewController.swift in Sources */,
732735
D1EDF7422C9F01270017FFA5 /* Issue2295View.swift in Sources */,
733736
D1A1CCA321A1879600263AD8 /* MainViewController.swift in Sources */,
737+
D12F67682CB10AE000AB63AB /* LivePhotoViewController.swift in Sources */,
734738
4BC0ED4A29A6EE78003E9CD1 /* Issue2035View.swift in Sources */,
735739
D1F06F3721AAEACF000B1C38 /* GIFViewController.swift in Sources */,
736740
4B120CA726B91BB70060B092 /* TransitionViewDemo.swift in Sources */,

0 commit comments

Comments
 (0)