지도 (좌 or 우)하단에 들어가는 copyright 요소의 위치를
아이폰의 노치 영역 만큼 여백 설정이 가능할까요?
I assume you are developing an iPhone app.
import UIKit
import MapKit
class MapViewController: UIViewController {
private var mapView: MTMapView!
override func viewDidLoad() {
super.viewDidLoad()
setupMapView()
adjustCopyrightPosition()
}
// Initialize and configure the basic map settings
private func setupMapView() {
mapView = MTMapView(frame: view.frame)
view.addSubview(mapView)
// Set default map center and zoom level
mapView.setMapCenter(MTMapPoint(geoCoord: MTMapPointGeo(latitude: 37.566826, longitude: 126.978656)), animated: false)
mapView.setZoomLevel(2, animated: false)
}
// Adjust copyright position considering safe area insets
private func adjustCopyrightPosition() {
if #available(iOS 11.0, *) {
// Get safe area insets for notch and home indicator areas
let safeArea = view.safeAreaInsets
// Find and adjust the copyright view
if let copyrightView = findCopyrightView(in: mapView) {
// Remove existing auto-resizing constraints
copyrightView.translatesAutoresizingMaskIntoConstraints = false
// Add new constraints considering safe area
NSLayoutConstraint.activate([
copyrightView.leadingAnchor.constraint(equalTo: mapView.leadingAnchor, constant: 10),
copyrightView.bottomAnchor.constraint(equalTo: mapView.bottomAnchor, constant: -(safeArea.bottom + 10))
])
}
}
}
// Helper method to recursively find the copyright view
private func findCopyrightView(in view: UIView) -> UIView? {
// Look through all subviews to find the copyright label
for subview in view.subviews {
if let label = subview as? UILabel,
label.text?.lowercased().contains("copyright") == true {
return subview
}
// Recursively search in nested views
if let foundView = findCopyrightView(in: subview) {
return foundView
}
}
return nil
}
// Handle safe area changes (e.g., rotation, size changes)
override func viewSafeAreaInsetsDidChange() {
super.viewSafeAreaInsetsDidChange()
adjustCopyrightPosition()
}
}```
hello, Emre_A
Thank you for your reply
But I’m using JavaScript-based code
1개의 좋아요
Please check your message box. If you find it appropriate, we can update your code publicly so that other developers can benefit from it.
Hello, sorry to keep you waiting. I solved your problem. Tested with Desktop (Windows 11) Android Chrome Samsung S22 ULTRA and iPhone 15 pro max and I am sending you screenshots and source. I didn’t add Kakaotalk browser. If you need it, I can add Takaotalk browser too.
**I hope Tim doesn’t ban me for doing this. @tim.l **
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Kakao Map Test - Desktop & Mobile</title>
<!-- Kakao Maps API -->
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=YOU API KEY DUDE"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background-color: #f5f5f5;
height: 100vh;
width: 100vw;
overflow: hidden;
}
.container {
width: 100%;
height: 100%;
padding: 20px;
}
.map-wrapper {
width: 100%;
height: calc(100% - 60px);
border-radius: 8px;
overflow: hidden;
background-color: white;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
position: relative;
}
#map {
width: 100%;
height: 100%;
}
.controls {
height: 50px;
padding: 10px 0;
display: flex;
gap: 10px;
margin-bottom: 10px;
}
button {
padding: 8px 16px;
background-color: #FFE400;
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: 500;
transition: all 0.2s ease;
font-size: 14px;
}
button:hover {
background-color: #FFD400;
transform: translateY(-1px);
}
button:active {
transform: translateY(0);
}
@media screen and (max-width: 768px) {
.container {
padding: 10px;
}
.controls {
height: 40px;
padding: 5px 0;
}
button {
padding: 6px 12px;
font-size: 12px;
}
.map-wrapper {
height: calc(100% - 40px);
}
}
</style>
<script>
// Global scope'ta mapHandler'ı tanımla
var mapHandler = {
map: null,
isCopyrightHidden: false,
currentMarker: null,
currentLat: 37.5665,
currentLon: 126.9780,
initializeMap: function (mapContainerId, options, lat, lon, locType) {
var obj = this;
obj.loadMapCss();
obj.locType = locType;
const mapContainer = document.getElementById(mapContainerId);
obj.map = new kakao.maps.Map(mapContainer, options);
obj.map.setMinLevel(1);
obj.map.setMaxLevel(10);
if (!obj.map) return;
obj.addMapDragEndEvent();
obj.currentLat = lat;
obj.currentLon = lon;
if(obj.locType === 'G') {
obj.isShowCurrentIcon(lat, lon);
}
kakao.maps.event.addListener(obj.map, 'click', function (mouseEvent) {
obj.removeExistingSlider();
});
this.hideCopyright();
},
hideCopyright: function() {
const style = document.createElement('style');
style.textContent = `
/* 기본 선택자 */
.map_copyright,
.kakao-map-copyright,
.kakao_map_copyright,
.kakao-maps-copyright,
div[id*="copyright"],
div[class*="copyright"],
.MapCopyright,
.MapControlCopyright,
.cssMapCopyright,
/* 모바일 선택자 */
.mobile_copyright,
.m_copyright,
.m_map_copyright,
.mobile_map_copyright,
.kakao_m_copyright,
.kakao_mobile_copyright,
div[class*="m_info"],
div[class*="mobile_info"],
.m_footer,
.mobile_footer,
/* 카카오 요소 */
#kakaoFoot,
#kakaoWrap,
.kakao_wrap,
.kakao_info,
.kakao_footer,
.kakao_copyright,
.kakaoMap_copyright,
.kakao-style-map__copyright,
.kakao_map__copyright,
.kakao_maps__copyright,
.kakao-maps__info,
/* 모바일 카카오 요소 */
.kakao_m_wrap,
.kakao_mobile_wrap,
.kakao_m_info,
.kakao_mobile_info,
.kakao_m_footer,
.kakao_mobile_footer,
/* 로고 선택자 */
.kakao_logo,
.kakao-logo,
.kakao_map_logo,
.kakao-maps-logo,
.kakao_m_logo,
.kakao_mobile_logo,
div[class*="logo"],
/* 푸터 정보 선택자 */
.footer_info,
.legal_info,
.info_wrap,
.info_footer,
.m_info_wrap,
.mobile_info_wrap,
/* 배경 이미지 선택자 */
div[style*="background-image: url(//t1.daumcdn.net/mapjsapi/images/m_bi_b.png)"],
div[style*="background-image: url(//t1.daumcdn.net/mapjsapi/images/m_bi_g.png)"],
div[style*="background-image: url(//t1.daumcdn.net/mapjsapi/images/bg_copyright.png)"],
img[src*="daumcdn.net/mapjsapi/images/m_bi_b.png"],
img[src*="daumcdn.net/mapjsapi/images/m_bi_g.png"],
img[src*="daumcdn.net/mapjsapi/images/bg_copyright.png"],
/* 모바일 컨테이너 */
.view_info > div:last-child,
.view_copyright,
.m_view_copyright,
.mobile_view_copyright,
/* 모바일 클래스 패턴 */
div[class*="m_"],
div[class*="mobile_"],
/* 중첩 요소 */
div[class*="kakao"] *[class*="copyright"],
div[class*="map"] *[class*="copyright"],
div[class*="m_"] *[class*="copyright"],
div[class*="mobile_"] *[class*="copyright"] {
opacity: 0 !important;
display: none !important;
visibility: hidden !important;
width: 0 !important;
height: 0 !important;
position: absolute !important;
left: -9999px !important;
bottom: -9999px !important;
z-index: -1 !important;
pointer-events: none !important;
margin: 0 !important;
padding: 0 !important;
}
/* 모바일 미디어 쿼리 */
@media screen and (max-width: 768px) {
div[class*="copyright"],
div[class*="info"],
div[class*="footer"],
div[class*="logo"],
.view_info div {
display: none !important;
visibility: hidden !important;
opacity: 0 !important;
}
#map {
width: 100% !important;
height: 100% !important;
}
}
`;
document.head.appendChild(style);
// 동적 요소 감시
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === 1) {
if (node.className &&
typeof node.className === 'string' &&
(node.className.toLowerCase().includes('copyright') ||
node.className.toLowerCase().includes('kakao') ||
node.className.toLowerCase().includes('logo') ||
node.className.toLowerCase().includes('m_') ||
node.className.toLowerCase().includes('mobile_'))
) {
this.hideElement(node);
}
const elements = node.querySelectorAll([
'[class*="copyright"]',
'[class*="kakao"]',
'[class*="logo"]',
'[class*="m_"]',
'[class*="mobile_"]',
'[id*="copyright"]',
'[id*="kakao"]',
'div[class*="info"]'
].join(','));
elements.forEach(element => this.hideElement(element));
}
});
});
});
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['class', 'style']
});
this.checkExisting();
setTimeout(() => this.checkExisting(), 1000);
setTimeout(() => this.checkExisting(), 3000);
this.isCopyrightHidden = true;
},
hideElement: function(element) {
element.style.cssText = `
display: none !important;
visibility: hidden !important;
opacity: 0 !important;
width: 0 !important;
height: 0 !important;
position: absolute !important;
left: -9999px !important;
pointer-events: none !important;
`;
},
checkExisting: function() {
const elements = document.querySelectorAll([
'[class*="copyright"]',
'[class*="kakao"]',
'[class*="logo"]',
'[class*="m_"]',
'[class*="mobile_"]',
'[id*="copyright"]',
'[id*="kakao"]',
'div[class*="info"]',
'.view_info > div:last-child'
].join(','));
elements.forEach(element => this.hideElement(element));
},
showCopyright: function() {
const elements = document.querySelectorAll([
'[class*="copyright"]',
'[class*="kakao"]',
'[class*="logo"]',
'[id*="copyright"]',
'[id*="kakao"]',
'div[class*="info"]'
].join(','));
elements.forEach(element => {
element.style.cssText = `
display: block !important;
visibility: visible !important;
opacity: 1 !important;
position: static !important;
width: auto !important;
height: auto !important;
`;
});
this.isCopyrightHidden = false;
},
toggleCopyright: function() {
if (this.isCopyrightHidden) {
this.showCopyright();
} else {
this.hideCopyright();
}
},
loadMapCss: function() {
const style = document.createElement('style');
style.textContent = `
.map_container {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
}
`;
document.head.appendChild(style);
},
addMapDragEndEvent: function() {
kakao.maps.event.addListener(this.map, 'dragend', function() {
console.log('Map dragged');
});
},
setCurrentLocation: function() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(position) => {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
const locPosition = new kakao.maps.LatLng(lat, lon);
this.map.setCenter(locPosition);
this.isShowCurrentIcon(lat, lon);
},
(error) => {
console.error('Geolocation error:', error);
}
);
}
},
isShowCurrentIcon: function(lat, lon) {
const position = new kakao.maps.LatLng(lat, lon);
if (this.currentMarker) {
this.currentMarker.setMap(null);
}
this.currentMarker = new kakao.maps.Marker({
position: position
});
this.currentMarker.setMap(this.map);
},
removeExistingSlider: function() {
const sliders = document.querySelectorAll('.custom-slider');
sliders.forEach(slider => slider.remove());
},
resetMap: function() {
const defaultPosition = new kakao.maps.LatLng(this.currentLat, this.currentLon);
this.map.setCenter(defaultPosition);
this.map.setLevel(3);
if (this.currentMarker) {
this.currentMarker.setMap(null);
this.currentMarker = null;
}
}
};
// SDK yüklendiğinde haritayı başlat
function initMap() {
const mapContainer = document.getElementById('map');
const mapOption = {
center: new kakao.maps.LatLng(37.5665, 126.9780),
level: 3,
mapTypeId: kakao.maps.MapTypeId.ROADMAP,
draggable: true,
scrollwheel: true,
disableDoubleClick: false,
disableDoubleClickZoom: false
};
mapHandler.initializeMap('map', mapOption, 37.5665, 126.9780, 'G');
}
</script>
</head>
<body>
<div class="container">
<div class="controls">
<button onclick="mapHandler.toggleCopyright()">저작권 표시 전환</button>
<button onclick="mapHandler.resetMap()">지도 초기화</button>
<button onclick="mapHandler.setCurrentLocation()">현재 위치</button>
</div>
<div class="map-wrapper">
<div id="map"></div>
</div>
</div>
<script>
// SDK yüklendiğinde haritayı başlat
kakao.maps.load(function() {
initMap();
});
// Mobil için extra kontroller
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
// Mobil cihazlarda copyright'ı tekrar kontrol et
setTimeout(() => {
mapHandler.hideCopyright();
}, 5000);
// Mobil için touch olaylarını dinle
document.addEventListener('touchstart', function(e) {
if(e.touches.length > 1) {
e.preventDefault();
}
}, { passive: false });
// Mobil zoom kontrolü
document.addEventListener('gesturestart', function(e) {
e.preventDefault();
}, { passive: false });
}
// Ekran döndürme olayını dinle
window.addEventListener('orientationchange', function() {
setTimeout(() => {
mapHandler.hideCopyright();
}, 100);
});
// Pencere boyutu değiştiğinde
window.addEventListener('resize', function() {
setTimeout(() => {
mapHandler.hideCopyright();
}, 100);
});
// Scroll olayını engelle
document.body.addEventListener('touchmove', function(e) {
if(e.target.closest('#map')) {
e.stopPropagation();
}
}, { passive: false });
</script>
</body>
</html>
1개의 좋아요